繁体   English   中英

git post-receive挂钩未在后台运行

[英]git post-receive hook not running in background

根据git文档 ,post-receive钩子实质上阻塞了仓库,直到它完成:

...客户端直到完成才断开连接,因此如果尝试执行可能需要很长时间的任何操作,请务必小心。

如果您需要挂钩来启动构建作业,然后在启动另一个作业(例如部署作业)之前轮询它的完成,则会导致问题。 例如,运行脚本时,构建服务器无法从存储库中获取。

我们还假设您完全没有能力将脚本放置在git服务器上,而整个nohup /usr/bin/env python /path/to/post_receive.py 2>&1 > /dev/null &这个问题类似的方法。

我们还假设您已经尝试了整个double os.fork() 'ing守护进程,与类似,还有其他一些问题(下面的示例代码无效 ),发现git仍在等待长时间运行的子进程完成之后完成挂钩。

pid = os.fork()
if pid == 0:
    os.setsid()
    pid = os.fork()
    if pid == 0:
        long_running_post_receive_function()
    else:
        os._exit(0)
else:
    for fd in range(0, 3):
        os.close(fd)
    os._exit(0)

那么,在这些限制下,有人能成功运行长时间运行的python post-receive钩子,而该钩子实际上在后台运行而不阻塞存储库吗?

编辑

工作最小的结构,没有异常处理...感谢@torek和@jthill

pid = os.fork()
if pid == 0:
    os.setsid()
    pid = os.fork()
    if pid == 0:
        for fd in range(0, 3):
            os.close(fd)
        long_running_post_receive_function()
    else:
        os._exit(0)
else:
    sys.exit()

您需要关闭所有描述符访问,以便ssh知道它将永远不会再获得任何数据。 换句话说,在描述符0到2上调用os.close 。实际上,您需要将其打开 ,因此最好将os.devnullos.dup2的结果描述符打开到0、1和2上(以实现真正的健壮性)软件确保os.open尚未返回值0 <= fd <= 2当然,如果是,那就没关系,只需将其放在适当的位置,然后将其余的值os.open

(您仍然还需要通常的双叉把戏,并且明智的做法是放弃会话ID等。在某些Unix派生的系统中,有一个名为daemon的库例程,该例程可能在libc或libutil中,可以完成所有操作一些细节不可避免地取决于操作系统,例如放弃控制终端的方式(如果有的话),但是,链接的Python特定答案缺少的主要内容是替换了stdin / stdout / stderr描述符。 )

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM