プロセスがSIGTERM
を受け取ると、シャットダウンして終了する必要があります。操作はできるだけ少なく、何も出力しません。
werkzeug.serving.run_simple
プロセスがSIGTERM
を受け取ると、通常、リターンコードは141(未処理/誤って処理されたSIGPIPE
症状)になり、リローダーを使用すると、プロセスはゾンビになります(ポートがバインドされたままなので、手動で強制終了します)。
sys.exit(0)
呼び出すだけのSIGTERM
シグナルハンドラーを追加するだけで問題を修正できますが(プロセスの誤動作がなくなるため)、実際に正しい修正であるかどうかはわかりません。
リローダーで実行すると、シグナルハンドラーをバインドします。 お役に立てば幸いです。
この修正はどのバージョンで行われますか? これは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の最新バージョンでは再現できないため、これを閉じます。
最も参考になるコメント
このバグにも見舞われました。私の場合、
docker stop
はwerkzeugを利用したサーバー(moto)にSIGTERM
を送信していましたが、サーバーは無視され、dockerはSIGKILL
それを強制終了しました。ゼロ以外の終了コードに変換します。回避策は、Dockerfile(
STOPSIGNAL SIGINT
)の優先停止信号としてSIGINT
(Ctrl + C)を指定すること