<p>werkzeug.serving.run_simple behandelt SIGTERM nicht richtig</p>

Erstellt am 9. Mai 2011  ·  11Kommentare  ·  Quelle: pallets/werkzeug

Wenn der Prozess SIGTERM empfängt, sollte er mit möglichst wenigen Vorgängen und ohne Drucken heruntergefahren und beendet werden.

Ein werkzeug.serving.run_simple -Prozess, der SIGTERM empfängt, führt im Allgemeinen zu einem Rückkehrcode von 141 (Symptom eines nicht / misshandelten SIGPIPE ), und wenn der Reloader verwendet wird, wird der Prozess zum Zombie (hat er) manuell getötet werden, da der Port gebunden bleibt).

Das Hinzufügen eines Signalhandlers für SIGTERM der einfach sys.exit(0) aufruft, reicht aus, um das Problem zu beheben (da es kein Fehlverhalten mehr gibt), aber ich bin nicht sicher, ob es die tatsächlich richtige Lösung ist.

bug

Hilfreichster Kommentar

Wurde auch von diesem Fehler getroffen, in meinem Fall schickte docker stop SIGTERM an einen werkzeug-betriebenen Server (moto), aber der Server ignorierte ihn und Docker tötete ihn mit SIGKILL in einen Exit-Code ungleich Null.

Die Problemumgehung bestand darin, SIGINT (Strg + C) als bevorzugtes Stoppsignal in Dockerfile ( STOPSIGNAL SIGINT ) anzugeben. Danach wurden die Container sauber heruntergefahren.

Alle 11 Kommentare

Ich binde jetzt einen Signalhandler, wenn ich mit Reloader laufe. Hoffentlich hilft das.

In welcher Version ist dieses Update? Dies ist in Flask 0.8 immer noch ein Problem.

Dies ist immer noch ein Problem. Es ist ziemlich ärgerlich, wenn Sie Flask mit einer IDE verwenden. Wenn Sie das Debuggen beenden, bleibt der Prozess bestehen und bedient weiterhin Anforderungen.

Ich öffne dieses Problem erneut, da es anscheinend weiterhin besteht. Siehe die folgende Diskussion des IRC heute.

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

Ich denke es ist immer noch relevant.

Wenn Sie os.kill(parent_id, signal.SIGTERM) ausführen, werden untergeordnete Prozesse nicht beendet.

Ich bin auch auf dieses Problem gestoßen, als ich die Testsuite für werkzeug.serving überarbeitet habe. Ich habe es umgangen, indem ich die gesamte Prozessgruppe beendet habe: https://github.com/mitsuhiko/werkzeug/blob/a00377315bbf02ec48fdad22c6bb08433fc1e9c1/tests/conftest.py#L158

Ich bin in Flask mit dem Debug-Modus auf dasselbe Problem gestoßen (use_debugger = True). Beim "übergeordneten" Prozess wird jedoch der Rückkehrcode 0 angezeigt. Ohne aktivierten Debug-Modus funktioniert SIGTERM einwandfrei und der Prozess wird mit Code 143 beendet. Python 2.7.5.

Wurde auch von diesem Fehler getroffen, in meinem Fall schickte docker stop SIGTERM an einen werkzeug-betriebenen Server (moto), aber der Server ignorierte ihn und Docker tötete ihn mit SIGKILL in einen Exit-Code ungleich Null.

Die Problemumgehung bestand darin, SIGINT (Strg + C) als bevorzugtes Stoppsignal in Dockerfile ( STOPSIGNAL SIGINT ) anzugeben. Danach wurden die Container sauber heruntergefahren.

Ich habe das gleiche Problem beim Ausführen einer Flask-App in Docker. STOPSIGNAL SIGINT jedoch immer noch nicht aus, um den Container anzuhalten. Ich muss SIGKILL .

Ich kann das Problem nicht neu erstellen. Ich habe dies mit dem offiziellen Python-Container mit den Tags 2.7 und 3.7 versucht. Ich habe die folgende Docker-Datei verwendet:

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"]

Und erstellte einen Container aus der Docker-Datei im Verzeichnis examples mit dem folgenden Befehl:

 docker build -t werkzeug-examples .

Ich würde dann den Container im interaktiven Modus ausführen und abbrechen mit:

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

Das Ausführen von docker ps zeigte, dass es mit 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

Das Ausführen des Containers und das Stoppen mit docker stop werkzeug-example ebenfalls mit 0 .

Hier ist das Ergebnis der Docker-Version auf dem Computer, auf dem ich die folgenden Befehle ausgeführt habe:

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

Können Sie ein Beispiel angeben, das das aufgetretene Problem reproduzieren kann?

Bis wir ein reproduzierbares Szenario erhalten, werde ich dieses schließen, da es in der neuesten Version von Docker und Werkzeug nicht reproduziert werden kann.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen