2017-01-05 5 views
0

で実行されていないフックをポストは、受信しますあなたが何かをしようとすると、長い時間がかかるかもしれないので注意してください。gitの<a href="https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks" rel="nofollow noreferrer">git documentation</a>レポは、完了するまで、実質的にブロックのポスト受けるフックによる背景

これは、ビルドジョブを開始するためにフックが必要な場合に問題を引き起こし、別のものを開始する前に完了のためにポーリングする、つまりdeployジョブです。たとえば、ビルドサーバーは、スクリプトが実行されている間はリポジトリからフェッチできません。

this questionに似たnohup /usr/bin/env python /path/to/post_receive.py 2>&1 > /dev/null &という方法でシェルコマンドとして実行するスクリプトをgitサーバーに配置することは絶対にできないとしましょう。

さんはまた、あなたがthisに似たデーモンプロセスをINGの、いくつかの他の質問(以下非稼働サンプルコード)全二重os.fork()」を試してみましたし、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ポスト受信フックで成功した人はいますか?無例外処理で最小限の構造ワーキング

EDIT

...おかげで@torekとSSHが知っているので、あなたは、すべての記述子へのアクセスを閉鎖する必要が

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() 
+0

また、ポスト受信フックが(非同期メッセージのように)単純なものでも、非同期メッセージを送信すると、コンシューマーデーモンがこれに気づき、その仕事をしてください。 – Mort

+0

私はこれが本当に私が達成しようとしているものの目的を敗北させる選択肢であることは確かに同意します –

+1

私は疲れていますが、間違った場所であなたのdup2()をやっているようです。 fdは長期実行プロセスではまだ開かれています。 – jthill

答えて

2

@jthillしますこれ以上のデータは得られません。換言すれば、0から2の記述子にos.closeと呼んでください。実際には、を開けばos.devnullos.dup2の結果の記述子を0,1,2で開く方が良いでしょう。(本当に堅牢なソフトウェアの場合はos.openもちろん、値0 <= fd <= 2を返していません。もしそうであれば、それは問題ありません。残りの部分はdup2-ingしておいてください。

(また、セッションIDなどを捨てることも賢明かもしれません)いくつかのUnix系システムでは、daemonというライブラリルーチンがあります。これはlibcまたはlibutilリンクされたPython固有の答えに欠けている主なものは、stdin/stdoutの置き換えです。/stderr記述子)

+0

私は間違いをしたり、何かを残していない限り、まだ動作していないようです。私は試したもののサンプルを使って質問を編集しました。 –

+0

最小限の構造が追加されました...ありがとう! –

関連する問題