<p>werkzeug.serving.run_simpleはSIGTERMを正しく処理しません</p>

作成日 2011年05月09日  ·  11コメント  ·  ソース: pallets/werkzeug

プロセスがSIGTERMを受け取ると、シャットダウンして終了する必要があります。操作はできるだけ少なく、何も出力しません。

werkzeug.serving.run_simpleプロセスがSIGTERMを受け取ると、通常、リターンコードは141(未処理/誤って処理されたSIGPIPE症状)になり、リローダーを使用すると、プロセスはゾンビになります(ポートがバインドされたままなので、手動で強制終了します)。

sys.exit(0)呼び出すだけのSIGTERMシグナルハンドラーを追加するだけで問題を修正できますが(プロセスの誤動作がなくなるため)、実際に正しい修正であるかどうかはわかりません。

bug

最も参考になるコメント

このバグにも見舞われました。私の場合、 docker stopはwerkzeugを利用したサーバー(moto)にSIGTERMを送信していましたが、サーバーは無視され、dockerはSIGKILLそれを強制終了しました。ゼロ以外の終了コードに変換します。

回避策は、Dockerfile( STOPSIGNAL SIGINT )の優先停止信号としてSIGINT (Ctrl + C)を指定すること

全てのコメント11件

リローダーで実行すると、シグナルハンドラーをバインドします。 お役に立てば幸いです。

この修正はどのバージョンで行われますか? これはFlask0.8でもまだ問題です。

これはまだ問題であり、IDEでFlaskを使用する場合は非常に面倒です。デバッグを停止すると、プロセスが持続し、リクエストを処理し続けます。

この問題は解決しないようですので、再開します。今日のIRCからの次のディスカッションを参照してください。

20:20 < mcdonc> can somebody fix flask's reloader so when you send the process a sigint it actually stops the child process
20:20 < untitaker> mcdonc: it seems to work for me
20:21 < untitaker> mcdonc: it used to cause problems but for me it's fixed in latest master
20:21 < mcdonc> ah good.  i just got some number of complaints from people who run it under supervisor.
20:22 < untitaker> mcdonc: you are talking about the one from the Py3 port?
20:22 < untitaker> released versions should work properly
20:22 < mcdonc> no.. i am talking about.. well.. yes, i dont actually know what i'm talking about ;-)  i dont use it, i just get people telling me they need to send a stop signal to the entire process group instead of to the process to make sure its killed.
20:23 < mcdonc> this is not recent.. for the last year or so
20:23 < mcdonc> why people run the reloader under supervisor (presumably in production) i cannot fathom
20:23 < mcdonc> but they do
20:24 < Alex_Gaynor> mcdonc: I've toyed with using supervisord in dev, FWIW
20:24 < Alex_Gaynor> mcdonc: for cases where you don't just have web proc, you've also got background daemons and such, it could be nice
[...]
20:32 < DasIch> untitaker: the supervisor issue is independent from the threading/thread issue
20:32 < untitaker> DasIch: ah okay
20:32 < untitaker> didn't know that
20:32 < untitaker> DasIch: is the reloader behaving weird in supervisor?
20:33 < DasIch> untitaker: I guess what happens if you run the reloader in supervisor is that supervisor kill the reloading process but that doesn't kill the process started by the reloader
20:34 < untitaker> DasIch: couldn't one write a wrapper shell script that kills both?
20:34 < untitaker> at least for now
20:34 < DasIch> untitaker: I think you shouldn't use the reloader in production
20:35 < untitaker> well yeah
20:35 < asdf`> (supervisord has a 'kill as group' thing)
20:35 < DasIch> right there is that as well
20:35 < asdf`> (it even mentions the werkzeug reloader in the docs paragraph about it!)
20:36 < mcdonc> yes i put it there
20:37 < asdf`> (then you might want to fix it, because AFAIR it actually says 'flask', while the reloader is part of werkzeug. But i admit 'flask' is something more people will know)
20:37 < mcdonc> nobody reads docs anyway ;)
20:38 < DasIch> I just wanted to mention I don't care unless someone creates an issue with a valid use case for that but apparently this seems to be it https://github.com/mitsuhiko/werkzeug/issues/58
20:38 < mcdonc> like alex said, it's not entirely crazy to want to use the reloader under supervisor in dev, esp. if your app is reliant on other processes being started
20:39 < mcdonc> i actually dont run my own apps under supervisor, but that's because i don't use a reloader, i just press ctrl-c.. because i'm a savage
20:40 < DasIch> I do use the reloader but I tend to save so often with bad syntax that I end up restarting manually all the time

私はそれがまだ関連していると思います。

os.kill(parent_id, signal.SIGTERM)しても、子プロセスは強制終了されません。

werkzeug.servingテストスイートを作り直しているときに、この問題も発生しました。 プロセスグループ全体を強制終了することで回避しました: https

デバッグモード(use_debugger = True)のFlaskでこれと同じ問題が発生しました。 ただし、「親」プロセスで戻りコード0が表示されます。 デバッグモードが有効になっていない場合、SIGTERMは正常に機能し、プロセスはコード143で終了します。Python2.7.5。

このバグにも見舞われました。私の場合、 docker stopはwerkzeugを利用したサーバー(moto)にSIGTERMを送信していましたが、サーバーは無視され、dockerはSIGKILLそれを強制終了しました。ゼロ以外の終了コードに変換します。

回避策は、Dockerfile( STOPSIGNAL SIGINT )の優先停止信号としてSIGINT (Ctrl + C)を指定すること

Docker内でFlaskアプリを実行しているときにも同じ問題が発生します。 ただし、 STOPSIGNAL SIGINTはまだコンテナを停止するのに十分ではありません。 SIGKILLを使用する必要があります。

問題を再現できません。 2.7および3.7タグ付きの公式Pythonコンテナでこれを試しました。 次のDockerfileを使用しました。

FROM python:2.7

WORKDIR /usr/src/app

RUN pip install click \
                werkzeug \
                sqlalchemy \
                jinja2

COPY . .

RUN python manage-shorty.py initdb

ENTRYPOINT ["python"]

CMD ["manage-shorty.py", "runserver"]

そして、次のコマンドを使用して、 examplesディレクトリのDockerfileからコンテナを構築しました。

 docker build -t werkzeug-examples .

次に、コンテナをインタラクティブモードで実行し、次のコマンドでキャンセルします。

$ docker run -it --name werkzeug-example werkzeug-examples
 * Running on http://localhost:5000/ (Press CTRL+C to quit)
 * Restarting with stat
^C

docker psを実行すると、 0で終了したことがわかりました。

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS                      PORTS               NAMES
8c708ea4ef77        werkzeug-examples   "python manage-short…"   About a minute ago   Exited (0) 58 seconds ago                       werkzeug-example

コンテナを実行してdocker stop werkzeug-example停止すると、 0終了します。

これらのコマンドを実行したコンピューターでのDockerバージョンの結果は次のとおりです。

Client: Docker Engine - Community
 Version:           18.09.2
 API version:       1.39
 Go version:        go1.10.8
 Git commit:        6247962
 Built:             Sun Feb 10 04:12:39 2019
 OS/Arch:           darwin/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          18.09.2
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.6
  Git commit:       6247962
  Built:            Sun Feb 10 04:13:06 2019
  OS/Arch:          linux/amd64
  Experimental:     false

発生している問題を再現できる例を提供できますか?

再現可能なシナリオが得られるまで、DockerとWerkzeugの最新バージョンでは再現できないため、これを閉じます。

このページは役に立ちましたか?
0 / 5 - 0 評価