因为目前我们的 Subversion 提交后挂钩执行时间太长,所以我一直在尝试加快速度。
我一直在考虑将实际的钩子作为后台进程来执行,以便svn commit
在实际钩子完成运行之前完成。
所以我创建了两个文件。
post-commit.bg
做一些耗时的事情:
sleep 10
而实际post-commit
在后台执行前者:
bash post-commit.bg &
当我从命令行运行时,post-commit
它很快就完成了,并且post-commit.bg
仍在运行。但是当我这样做时,svn commit
它仍然需要 10 秒钟!
SVN 是否以某种方式禁止后台进程或者我在这里做错了什么?
答案1
我刚刚在本地确认了这一点。这似乎是设计使然:
什么时候运行钩, SVN调用 apr_proc_wait
等待 apr_proc_wait被设计为等到所有子进程退出后再返回。这是为了避免僵尸(无主)进程淹没系统。
你可能如果您找到一种方法来分离该进程(即守护进程模式),那么您会取得一些成功,但我不确定。
您可能会发现在某处运行另一个进程会更好,该进程会响应来自 svn 的 ping 来做一些工作 -哈德森这是我的选择 - 工作可以通过wget 位于提交后钩子中或者您可以让它为您进行投票颠覆,这取决于您想做什么。
答案2
您还需要重定向 stderr:
bash 后提交.bg 2>&1 &
这将使进程与父进程分离(就 subversion 而言),并让客户端无需等待即可完成。我遇到了同样的问题,这就是解决办法。
答案3
在 Linux 上,只需使用nohup
:
nohup sh -c 'sleep 10' &
答案4
我成功测试了一些无法支持 Subversion 钩子的 Python 代码。您必须专门重定向 stdout 和 stderr 的输出,如上文 Bert Huijben 所指出的。请参阅下面的代码示例。
提交后文件:
#!/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:])
它调用了我命名为 postNotify.py 的脚本:
#!/usr/bin/env python2.7
import os, sys, time
time.sleep(15)
os.stderr.write('Generic Problem\n')
sys.exit(1)
*编辑 1 - 我应该提到这是针对 Subversion 1.9.3