簡體   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