5

Because currently our Subversion post-commit hooks take way too long to execute I've been trying to speed things up.

I've been thinking about executing the actual hooks as a background process, so that the svn commit would complete before the actual hooks finish running.

So I created two files.

A post-commit.bg that does something time-consuming:

sleep 10

And the actual post-commit itself that executes the former in background:

bash post-commit.bg &

When I run post-commit from command line it finishes quickly, leaving post-commit.bg still running. But when I do svn commit it still takes 10 seconds!

Are background processes somehow disallowed by SVN or what could I be doing wrong here?

6 Answers 6

5

I just confirmed this locally. It appears to be by design:

When running hooks, svn calls apr_proc_wait

apr_proc_wait is designed to wait until all child processes exit before returning. This is to avoid zombie(unowned) processes overrunning the system.

You might have some success if you find a way to detach the process (ie, daemon mode), but I'm not sure.

You might find it better to run another process somewhere which does some work in response to a ping from svn - Hudson is my choice for this sort of thing - jobs can be triggered by a wget in a post-commit hook, or you can have it poll subversion for you, depending on what you want to do.

2
  • I guess I have to get into that continuous-integration-thing finally. Sep 15, 2009 at 9:49
  • 1
    You have to detach stdin, stdout and stderr to allow subversion to continue. (You can do this when calling your program, but how depends on your shell). Sep 16, 2009 at 13:13
12

You need to redirect stderr also:

bash post-commit.bg 2>&1 &

That will detach the process from the parent process (as far as subversion is concerned) and let the client finish without waiting. I had this same problem, and that was the fix.

2

On Linux, just use nohup:

nohup sh -c 'sleep 10' &
2

For windows user:

This topic has already been discussed here: Running another program in Windows bat file and not create child process

1

I successfully tested some Python code that won't hold up the subversion hooks. You have to specifically redirect the output of stdout and stderr as pointed out by Bert Huijben above. See code example below.

post-commit file:

#!/usr/bin/env python2.7

import os, sys, subprocess

def main(args):
    try:
        #Subversion hook will still wait even though you didn't redirect stdout or stderr
        #subprocess.Popen(['<PATH_TO_SVN>/hooks/postNotify.py', args[0], args[1]])
        #This works however
        devNull = open(os.devnull, 'w')
        subprocess.Popen(['<PATH_TO_SVN>/hooks/postNotify.py', args[0], args[1]], stdout=devNull, stderr=devNull)
        devNull.close()
    except BaseException as e:
        sys.stderr.write('Failed to launch notify script with error {}\n'.format(str(e))
        sys.exit(1)
    sys.exit(0)

if __name__ == '__main__':
    main(sys.argv[1:])

Which called the script I named postNotify.py:

#!/usr/bin/env python2.7

import os, sys, time

time.sleep(15)
os.stderr.write('Generic Problem\n')
sys.exit(1)

*edit 1 - I should mention this was against Subversion 1.9.3

0

I think dehmann is right. you can also register post-commit.bg to be executed as a batch process - on linux, use the 'batch' command (at) for that; but pay attention to the potential reshuffling...

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .