<p>werkzeug.serving.run_simple no maneja SIGTERM correctamente</p>

Creado en 9 may. 2011  ·  11Comentarios  ·  Fuente: pallets/werkzeug

Cuando el proceso recibe SIGTERM , debe cerrarse y salir, con la menor cantidad de operaciones posible y sin imprimir nada.

Un proceso werkzeug.serving.run_simple que recibe SIGTERM generalmente resulta en un código de retorno de 141 (síntoma de un SIGPIPE no manejado / mal manejado), y cuando se usa el recargador, el proceso se vuelve zombie (tiene para ser eliminado manualmente, ya que el puerto permanece vinculado).

Agregar un controlador de señal para SIGTERM que simplemente invoca sys.exit(0) es suficiente para solucionar el problema (ya que no hay más mal comportamiento del proceso), pero no estoy seguro de que sea la solución realmente correcta.

bug

Comentario más útil

También me golpeó este error, en mi caso docker stop estaba enviando SIGTERM al servidor con tecnología werkzeug (moto), pero el servidor lo ignoró y luego la ventana acoplable lo mató con SIGKILL resultante en un código de salida distinto de cero.

La solución fue especificar SIGINT (Ctrl + C) como una señal de parada preferida en Dockerfile ( STOPSIGNAL SIGINT ), después de eso, los contenedores se cerraron limpiamente.

Todos 11 comentarios

Ato un manejador de señales ahora cuando lo ejecuto con recargador. Espero que ayude.

¿En qué versión está esta solución? Esto sigue siendo un problema en Flask 0.8.

Esto sigue siendo un problema, es bastante molesto cuando se usa Flask con un IDE; cada vez que deja de depurar, el proceso persiste y continúa atendiendo solicitudes.

Estoy reabriendo este problema ya que parece persistir, vea la siguiente discusión del IRC hoy.

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

Creo que sigue siendo relevante.

Hacer os.kill(parent_id, signal.SIGTERM) no mata los procesos secundarios.

También encontré este problema al reelaborar el conjunto de pruebas por werkzeug.serving . Lo solucioné matando a todo el grupo de procesos: https://github.com/mitsuhiko/werkzeug/blob/a00377315bbf02ec48fdad22c6bb08433fc1e9c1/tests/conftest.py#L158

Me encontré con este mismo problema en Flask con el modo de depuración (use_debugger = True). Sin embargo, veo un código de retorno de 0 en el proceso "principal". Sin el modo de depuración habilitado, SIGTERM funciona bien y el proceso finaliza con el código 143. Python 2.7.5.

También me golpeó este error, en mi caso docker stop estaba enviando SIGTERM al servidor con tecnología werkzeug (moto), pero el servidor lo ignoró y luego la ventana acoplable lo mató con SIGKILL resultante en un código de salida distinto de cero.

La solución fue especificar SIGINT (Ctrl + C) como una señal de parada preferida en Dockerfile ( STOPSIGNAL SIGINT ), después de eso, los contenedores se cerraron limpiamente.

Tengo el mismo problema al ejecutar una aplicación Flask dentro de Docker; sin embargo, STOPSIGNAL SIGINT todavía no es suficiente para detener el contenedor. Tengo que usar SIGKILL .

No puedo recrear el problema. He intentado esto con el contenedor oficial de Python con la etiqueta 2.7 y 3.7. Usé el siguiente 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"]

Y construyó un contenedor desde el Dockerfile en el directorio examples con el comando:

 docker build -t werkzeug-examples .

Luego ejecutaría el contenedor en modo interactivo y cancelaría con:

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

Ejecutar docker ps mostró que salió con 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

Ejecutar el contenedor y detenerse con docker stop werkzeug-example también sale con 0 .

Aquí está el resultado de la versión de Docker en la computadora en la que ejecuté estos comandos:

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

¿Puede proporcionar un ejemplo que pueda reproducir el problema que está experimentando?

Hasta que podamos obtener un escenario reproducible, cerraré esto, ya que no se puede reproducir en la última versión de Docker y Werkzeug.

¿Fue útil esta página
0 / 5 - 0 calificaciones