Werkzeug: Werkzeug se bloquea después de escribir en una tubería cerrada

Creado en 20 jun. 2016  ·  41Comentarios  ·  Fuente: pallets/werkzeug

Tengo un servidor Werkzeug que se ejecuta detrás de NGINX. Cuando un cliente se desconecta mientras espera que el servidor Werkzeug responda, NGINX cierra la tubería a Werkzeug. Cuando el programa Python escribe la respuesta a Werkzeug, se produce la siguiente excepción y Werkzeug se bloquea:

Rastreo (llamadas recientes más última):
Archivo "server.py", línea 81, en
app.run (host = args.host, port = args.port, debug = False)
Archivo "/usr/local/lib/python2.7/dist-packages/flask/app.py", línea 843, en ejecución
run_simple (host, port, self, ** opciones)
Archivo "/usr/local/lib/python2.7/dist-packages/werkzeug/serving.py", línea 694, en run_simple
interno()
Archivo "/usr/local/lib/python2.7/dist-packages/werkzeug/serving.py", línea 659, en el interior
srv.serve_forever ()
Archivo "/usr/local/lib/python2.7/dist-packages/werkzeug/serving.py", línea 499, en serve_forever
HTTPServer.serve_forever (auto)
Archivo "/usr/lib/python2.7/SocketServer.py", línea 238, en serve_forever
self._handle_request_noblock ()
Archivo "/usr/lib/python2.7/SocketServer.py", línea 297, en _handle_request_noblock
self.handle_error (solicitud, dirección_cliente)
Archivo "/usr/lib/python2.7/SocketServer.py", línea 295, en _handle_request_noblock
self.process_request (solicitud, dirección_cliente)
Archivo "/usr/lib/python2.7/SocketServer.py", línea 321, en process_request
self.finish_request (solicitud, dirección_cliente)
Archivo "/usr/lib/python2.7/SocketServer.py", línea 334, en finish_request
self.RequestHandlerClass (solicitud, dirección_cliente, self)
Archivo "/usr/lib/python2.7/SocketServer.py", línea 651, en init
self.finish ()
Archivo "/usr/lib/python2.7/SocketServer.py", línea 710, al final
self.wfile.close ()
Archivo "/usr/lib/python2.7/socket.py", línea 279, de cerca
self.flush ()
Archivo "/usr/lib/python2.7/socket.py", línea 303, al ras
self._sock.sendall (ver [write_offset: write_offset + buffer_size])
socket.error: [Errno 32] Tubería rota

¿Hay alguna opción de configuración que me falta para evitar que se bloquee? Normalmente se detectan todas las excepciones y se devuelve un error 500, y el servidor permanece activo.

Comentario más útil

Guiado por la reciente confirmación de corrección, pude solucionar este problema llamando a app.run con passthrough_errors = False. YMMV

Todos 41 comentarios

Utilice un servidor WSGI de producción como Gunicorn o uWSGI, no el servidor de desarrollo Werkzeug.

Tengo un problema muy similar, excepto que estoy usando el servidor de desarrollo Werkzeug para el desarrollo (que es, AFAICT, su uso previsto), es decir, con el navegador conectado directamente al puerto 5000.

El error ocurre varias veces por hora, lo que obliga a un reinicio manual del servidor para seguir desarrollándose.

Aquí hay un rastreo:

Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 801, in __bootstrap_inner
    self.run()
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 754, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/Users/fermigier/envs/extranet-spr/lib/python2.7/site-packages/werkzeug/serving.py", line 659, in inner
    srv.serve_forever()
  File "/Users/fermigier/envs/extranet-spr/lib/python2.7/site-packages/werkzeug/serving.py", line 499, in serve_forever
    HTTPServer.serve_forever(self)
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 238, in serve_forever
    self._handle_request_noblock()
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 297, in _handle_request_noblock
    self.handle_error(request, client_address)
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 295, in _handle_request_noblock
    self.process_request(request, client_address)
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 321, in process_request
    self.finish_request(request, client_address)
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 334, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 655, in __init__
    self.handle()
  File "/Users/fermigier/envs/extranet-spr/lib/python2.7/site-packages/werkzeug/serving.py", line 216, in handle
    rv = BaseHTTPRequestHandler.handle(self)
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/BaseHTTPServer.py", line 340, in handle
    self.handle_one_request()
  File "/Users/fermigier/envs/extranet-spr/lib/python2.7/site-packages/werkzeug/serving.py", line 251, in handle_one_request
    return self.run_wsgi()
  File "/Users/fermigier/envs/extranet-spr/lib/python2.7/site-packages/werkzeug/serving.py", line 193, in run_wsgi
    execute(self.server.app)
  File "/Users/fermigier/envs/extranet-spr/lib/python2.7/site-packages/werkzeug/serving.py", line 186, in execute
    write(b'')
  File "/Users/fermigier/envs/extranet-spr/lib/python2.7/site-packages/werkzeug/serving.py", line 152, in write
    self.send_header(key, value)
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/BaseHTTPServer.py", line 401, in send_header
    self.wfile.write("%s: %s\r\n" % (keyword, value))
IOError: [Errno 32] Broken pipe

Experimento el mismo problema que @sfermigier con el servidor de desarrollo ( debug=True ) y tengo el mismo error de rastreo.

Este comportamiento ocurre generalmente en un caso muy simple: está utilizando algún tipo de funciones de autocompletar. El navegador inicia una conexión para los tokens de consulta y luego se detiene e inicia otra solicitud de más tokens. Terminarás con muchas tuberías rotas. Y esto no fue un problema hasta la última versión, lo que hace que el servidor de desarrollo esté completamente bloqueado.
Por lo tanto, sugerir el uso de un servidor de aplicaciones con todas las funciones es una buena solución, pero sigo viendo un problema aquí. Un problema de desarrollo, por supuesto, pero el hecho de que sea tan común activarlo hace que resulte perturbador para muchos desarrolladores que no están acostumbrados a _protocolos internos_.
Una tubería rota es muy común (piense en una solicitud larga por error y el desarrollador presionando el botón de parada del navegador) y no debería romper el servidor de desarrollo.
Solo es mi opinión. :)

@xcash

Este comportamiento ocurre generalmente en un caso muy simple: está utilizando algún tipo de funciones de autocompletar. El navegador inicia una conexión para los tokens de consulta y luego se detiene e inicia otra solicitud de más tokens.

Si está relacionado, puedo confirmar que tengo este problema usando browsersync con gulp.js .

¿Alguien tiene una solución que no incluya ejecutar un servidor WSGI? Parece que me estoy encontrando con este problema con los bots que realizan un escaneo SYN contra mi host.

@glennzw ¿ puede ser más específico en su entorno? Los bots no deben tener acceso a su servidor de desarrollo público en la web abierta. :) En tal situación, como un anfitrión de demostración para clientes, siempre es mejor usar al menos un servidor de aplicaciones real como gunicorn, que tiene una huella realmente pequeña.

FWIW, no he estado mucho al día con los lanzamientos y este problema (muy molesto) comenzó a sucederme en algún momento entre mayo y agosto de 2016, lo mejor que puedo decir. Agregué esto a mi setup.py install_requires = ['Werkzeug<0.11', 'flask<0.11', ... , que parece solucionar el problema (IME, ¿simplemente anclar Werkzeug no pareció funcionar?)

Para mí, el caso de la duplicación fue bastante simple: cargue una página, pero no deje que termine de cargarse. Es decir, simplemente active _cualquier_ error de tubería rota, y el servidor web se bloqueará y no podrá atender cualquier otra solicitud. En mi humilde opinión, los servidores web no pueden _caerse_ cuando un cliente cierra la conexión prematuramente, incluso los de desarrollo.

¿Podría ser que todos ustedes tienen passthrough_errors alguna parte?

@untitaker en ese caso, pallets / matraz # 1674 pallets / matraz # 1679 pallets / matraz # 1928 posiblemente relacionado?

No lo sé, me gustaría que lo confirmara uno de los reporteros.

El 26 de agosto de 2016 a las 17:05:25 CEST, David Lord [email protected] escribió:

@untitaker en ese caso, paletas / matraz # 1674 paletas / matraz # 1679
paletas / matraz # 1928 posiblemente relacionado?

Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente o véalo en GitHub:
https://github.com/pallets/werkzeug/issues/954#issuecomment -242761250

Enviado desde mi dispositivo Android con K-9 Mail. Por favor, disculpe mi brevedad.

cc @miguelgrinberg

Creo que Werkzeug debería manejar los errores de restablecimiento de conexiones y tuberías rotas. Estos realmente no son una indicación de un error, el cliente simplemente se fue. En este caso, parece que se debe generar una excepción especial, una que sea reconocida por el método catch-all anterior como una para ignorar, incluso si se establece el paso de error.

Así es como lo hace Gunicorn: https://github.com/benoitc/gunicorn/blob/39f62ac66beaf83ceccefbfabd5e3af7735d2aff/gunicorn/workers/sync.py#L151 -L154

Eso es lo que se supone que debe hacer. Estoy tratando de averiguar cómo reproducir
este comportamiento, pero todavía no hay un caso de prueba claro disponible. De ahí la pregunta
aproximadamente passthrough_errors .

Sospecho que esto no es un error en Werkzeug, y que el navegador del usuario
simplemente tiene una conexión aún abierta que bloquea otras solicitudes (en lugar de la
bloqueo del servidor). Si cierra su navegador y vuelve a abrir, el servidor debería
funcionar de nuevo.

El viernes 26 de agosto de 2016 a las 11:54:16 AM -0700, Miguel Grinberg escribió:

Creo que Werkzeug debería manejar los errores de restablecimiento de conexiones y tuberías rotas. Estos realmente no son una indicación de un error, el cliente simplemente se fue. En este caso, parece que se debe generar una excepción especial, una que sea reconocida por el método catch-all anterior como una para ignorar, incluso si se establece el paso de error.

Así es como lo hace Gunicorn: https://github.com/benoitc/gunicorn/blob/39f62ac66beaf83ceccefbfabd5e3af7735d2aff/gunicorn/workers/sync.py#L151 -L154

Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente o véalo en GitHub:
https://github.com/pallets/werkzeug/issues/954#issuecomment -242821084

Ah, y se muestran errores de tubería rota, sí, pero nunca deben colgar el servidor como se describe. Ver comentario anterior sobre el posible motivo.

Probé de nuevo los últimos bits y sigo viendo el mismo comportamiento en mi entorno. Pero como parecías tener problemas para reproducir, traté de explicar por qué soy especial.

import time
from flask import Flask
app = Flask(__name__)


@app.route('/')
def hello_world():
    time.sleep(5)
    return 'Hello, World!'


if __name__ == "__main__":
    app.run()

Funciona como se esperaba con flask run pero el servidor web fallaría si cierra su navegador web antes de dejar que la respuesta se procese cuando se inicia a través de python hello.py

Parece que una parte de su respuesta se perdió.

El viernes 26 de agosto de 2016 a las 12:29:39 PM -0700, Clayg escribió:

Probé de nuevo los últimos bits y sigo viendo el mismo comportamiento en mi entorno. Pero como parecías tener problemas para reproducir, traté de explicar por qué soy especial.

You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub:
https://github.com/pallets/werkzeug/issues/954#issuecomment-242829536

sí, en slack triple-ticks es cómo se bloquea la cotización y ctrl-return es cómo se cambia la línea
en github, triple-ticks es la forma de bloquear la cotización, pero ctrl-return es la forma de enviar
... de todos modos ... memoria muscular

Edité mi publicación inmediatamente después de enviarla para terminar, y solo respondo porque parece que estás respondiendo por correo electrónico y no estoy seguro de que github te envíe otro aviso después de mi edición.

No puedo reproducir con la prueba de sueño de @clayg anterior. De hecho, no obtengo el error de tubería rota en absoluto. Cierro el navegador antes de que la solicitud devuelva una respuesta, pero Werkzeug lleva a cabo la solicitud hasta el final de todos modos, imprime la línea de registro 200 en la consola y no muestra ningún error.

También probé el mismo truco usando mi ejemplo de transmisión de video de matraz que usa una respuesta de transmisión para proporcionar cuadros de video en una transmisión interminable, e incluso para ese, puedo cerrar el navegador y la solicitud finaliza sin ningún error. Este es extraño, porque estoy seguro de que en el pasado esta aplicación desencadenaría un error de tubería rota en la consola antes de finalizar la solicitud.

De hecho, hablé demasiado pronto. Puedo reproducir todo el tiempo con mi aplicación de transmisión de video cuando uso Python 2.7. No puedo reproducir en 3.5. Todos los seguimientos de pila anteriores son para 2.7, así que téngalo en cuenta si está probando con Python 3.

Otro dato interesante. Si se ejecuta con el cargador, cuando el proceso hijo sale, el proceso maestro que ejecuta el cargador inicia otro, por lo que no hay interrupción. Pero si está ejecutando el servidor sin el cargador, el error de tubería rota lo devuelve a la consola.

Editar: ignore el cargador que inicia otra parte del proceso, eso no parece estar sucediendo y, en cambio, probablemente estaba viendo el efecto de cambiar la configuración del error de paso a través.

Bien, aquí está el análisis de lo que creo que está sucediendo:

  • El cliente se marcha a mitad de la solicitud.
  • La solicitud continúa. La conexión del socket parece estar almacenada en búfer, por lo que, en la mayoría de los casos, las escrituras en el socket no causarán ningún problema.
  • Una vez que finaliza la solicitud, la clase de servidor de socket emitirá un flush() en el socket. Este fue el tema de un antiguo error en la biblioteca de Python que actualmente está corregido: http://bugs.python.org/issue14574. La solución en esta solución fue capturar socket.error e ignorarlo.
  • Luego, el servidor de socket intenta cerrar la conexión. Este es el siguiente marco de pila, del seguimiento del OP:

File "/usr/lib/python2.7/SocketServer.py", line 710, in finish self.wfile.close()

  • Desafortunadamente, en Python 2.7, lo primero que hace el método socket.close() es vaciar de nuevo:

File "/usr/lib/python2.7/socket.py", line 279, in close self.flush()

  • Este segundo intento de descarga no está protegido con un try / except, por lo que genera la excepción EPIPE.
  • El servidor de socket detecta la excepción y luego la entrega al método handle_error() del servidor.
  • La implementación de Werkzeug de handle_error() mira la configuración de passthrough_errors , y dado que siempre lo tenemos configurado en True , vuelve a generar el error EPIPE y deja que burbujee hasta el cima.

El código de socket en Python 3 es completamente diferente y, en particular, no parece tener ninguna llamada de descarga sin try / excepts a su alrededor. El error EPIPE ni siquiera llega a Werkzeug cuando se usa Python 3.

¿Incluso tenemos passthrough_errors establecido en verdadero? En Werkzeug es falso por defecto.

El 27 de agosto de 2016 a las 02:10:13 CEST, Miguel Grinberg [email protected] escribió:

Bien, aquí está el análisis de lo que creo que está sucediendo:

  • El cliente se marcha a mitad de la solicitud.
  • La solicitud continúa. La conexión del enchufe parece estar
    almacenado en búfer, por lo que en la mayoría de los casos, las escrituras en el socket no causarán
    problemas.
  • Una vez que finaliza la solicitud, la clase del servidor de socket emitirá un flush()
    en el enchufe. Este fue el tema de un antiguo error en la biblioteca de Python
    que está arreglado actualmente: http://bugs.python.org/issue14574. los
    La solución en esta solución fue capturar socket.error e ignorarlo.
  • Luego, el servidor de socket intenta cerrar la conexión. Este es el
    siguiente marco de pila, desde el backtrace del OP:
 File "/usr/lib/python2.7/SocketServer.py", line 710, in finish
 self.wfile.close()

  • Desafortunadamente, en Python 2.7, lo primero que socket.close()
    el método es enjuagar de nuevo:
 File "/usr/lib/python2.7/socket.py", line 279, in close
 self.flush()

  • Este segundo intento de color no está protegido con un intento / excepto, por lo que
    genera la excepción EPIPE.
  • El servidor de socket detecta la excepción y luego la entrega al
    método handle_error() del servidor.
  • La implementación de Werkzeug de handle_error() mira el
    passthrough_errors configuración, y dado que siempre tenemos esto configurado en
    True , vuelve a generar el error EPIPE y deja que suba hasta arriba.

El código de socket en Python 3 es completamente diferente y, en particular,
no parece tener ninguna llamada de descarga sin try / excepts alrededor
ellos. El error EPIPE ni siquiera aparece en Werkzeug cuando se usa
Python 3.

Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente o véalo en GitHub:
https://github.com/pallets/werkzeug/issues/954#issuecomment -242881523

Enviado desde mi dispositivo Android con K-9 Mail. Por favor, disculpe mi brevedad.

Oh, ejem: https://github.com/pallets/flask/pull/1679

Creo que passthrough_errors debería depender de app.debug . NVM, es inútil

No veo otra opción que revertir ese PR en realidad. passthrough_errors=True simplemente hace lo que se supone que debe hacer, lo cual no es un buen comportamiento predeterminado si uno no ha adjuntado un depurador al programa.

No importa, encontré otra forma. Dos RP:

Dado que ambos son cambios de comportamiento en un sentido amplio, prefiero no respaldarlos.

Creo que https://github.com/pallets/flask/pull/1996 es una solución aceptable. Lo importante es que corrige el caso común en el que no desea que se propaguen las excepciones. Si desea propagar, entonces está depurando y, en ese caso, hacer que el error de socket se propague cuando no debería no es un gran problema.

Sin embargo, la solución https://github.com/pallets/werkzeug/pull/998 no es excelente. La aplicación podría generar estas excepciones legítimamente a partir de algo que está haciendo con sockets en sus propios controladores, y también se silenciarían. La solución ideal sería que se detecten en el lugar en el que ocurren y luego se vuelvan a generar como una clase de excepción personalizada que handle_error pueda reconocer e ignorar. Dado que probablemente no queremos cambiar o sobrecargar SocketServer , creo que mi voto es dejar esta parte como está. Obtendrá el EPIPE volcado a la consola, pero solo en Python 2, y al menos no detendrá el servidor después de que se aplique la otra solución. Es inofensivo y es un comportamiento que existía en el pasado, antes de que hiciera el passthrough_errors cambio.

Sin embargo, el comportamiento que describe solo ocurre con PASSTHROUGH_ERRORS habilitado. De lo contrario, la excepción se captura desde Flask.

Sin embargo, creo que esta mejora cosmética no vale la pena.

El 27 de agosto de 2016 a las 18:29:30 CEST, Miguel Grinberg [email protected] escribió:

Creo que https://github.com/pallets/flask/pull/1996 es aceptable
solución. Lo importante es que corrige el caso común en el que
no desea que se propaguen las excepciones. Si quieres propagarte,
entonces estás depurando, y en ese caso obteniendo el socket.error
propagado cuando no debería no es un gran problema.

La solución https://github.com/pallets/werkzeug/pull/998 no es excelente
aunque. La aplicación puede generar estas excepciones legítimamente desde
algo que está haciendo con sockets en sus propios controladores, y esos
ser silenciado también. La solución ideal sería que estos se atrapen
en el lugar donde ocurren y luego se vuelven a plantear como una excepción personalizada
clase que handle_error puede reconocer e ignorar. Dado que nosotros
probablemente no quiera cambiar o sobrecargar SocketServer , creo que mi
votar es dejar esta parte como está. Obtendrá el EPIPE descargado a
la consola, pero solo en Python 2, y al menos no se detendrá
el servidor después de la otra solución. Es inofensivo y es un
comportamiento que existía en el pasado, antes de que hiciera el
passthrough_errors cambio.

Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente o véalo en GitHub:
https://github.com/pallets/werkzeug/issues/954#issuecomment -242926832

Enviado desde mi dispositivo Android con K-9 Mail. Por favor, disculpe mi brevedad.

Fijo en master.

Sin embargo, el comportamiento que describe solo ocurre con PASSTHROUGH_ERRORS habilitado

Sí, omití ese detalle. Pero este cambio afectaría incluso a Python 3, donde nada de esto es un problema. En Py3, con los errores de paso habilitados, se silenciaría un error de socket legítimo generado por la aplicación.

master parece wfm, esperando el próximo lanzamiento, ¡gracias!

Hola, uso un servidor de desarrollo Werkzeug que se ejecuta detrás de NGINX, estoy enfrentando el mismo problema, ¿alguien podría ayudarme con esto?
11:13:11 web.1 | 127.0.0.1 - - [15/Sep/2016 11:13:11] "GET /api/method/frappe.utils.print_format.download_pdf?doctype=Purchase%20Order&name=PO-00001&format=PO&no_letterhead=0 HTTP/1.1" 200 - 11:13:11 web.1 | Error on request: 11:13:11 web.1 | Traceback (most recent call last): 11:13:11 web.1 | File "/home/ommi/frappe-bench/env/lib/python2.7/site-packages/werkzeug/serving.py", line 193, in run_wsgi 11:13:11 web.1 | execute(self.server.app) 11:13:11 web.1 | File "/home/ommi/frappe-bench/env/lib/python2.7/site-packages/werkzeug/serving.py", line 184, in execute 11:13:11 web.1 | write(data) 11:13:11 web.1 | File "/home/ommi/frappe-bench/env/lib/python2.7/site-packages/werkzeug/serving.py", line 152, in write 11:13:11 web.1 | self.send_header(key, value) 11:13:11 web.1 | File "/usr/lib/python2.7/BaseHTTPServer.py", line 401, in send_header 11:13:11 web.1 | self.wfile.write("%s: %s\r\n" % (keyword, value)) 11:13:11 web.1 | IOError: [Errno 32] Broken pipe

Por favor ayuda

Ragav usa otro servidor de aplicaciones en lugar del desarrollador integrado de werkzeug
servidor, como gunicorn. Es la única solución en este momento.

2016-09-15 8:07 GMT + 02: 00 Ragav [email protected] :

Hola, uso un servidor de desarrollo Werkzeug que se ejecuta detrás de NGINX, estoy frente a
mismo problema, ¿alguien podría ayudarme con esto? ''
11:13:11 web.1 | 127.0.0.1 - - [15 / Sep / 2016 11:13:11] "OBTENER
/api/method/frappe.utils.print_format.download_pdf?
doctype = Compra% 20Order & name = PO-00001 & format = PO & no_letterhead = 0
HTTP / 1.1 "200 -
11:13:11 web.1 | Error a pedido:
11:13:11 web.1 | Rastreo (llamadas recientes más última):
11:13:11 web.1 | Archivo "/ home / ommi / frappe-bench / env /
lib / python2.7 / site-packages / werkzeug / serve.py ", línea 193, en run_wsgi
11:13:11 web.1 | ejecutar (self.server.app)
11:13:11 web.1 | Archivo "/ home / ommi / frappe-bench / env /
lib / python2.7 / site-packages / werkzeug / serve.py ", línea 184, en ejecución
11:13:11 web.1 | escribir (datos)
11:13:11 web.1 | Archivo "/ home / ommi / frappe-bench / env /
lib / python2.7 / site-packages / werkzeug / serve.py ", línea 152, en escritura
11:13:11 web.1 | self.send_header (clave, valor)
11:13:11 web.1 | Archivo "/usr/lib/python2.7/BaseHTTPServer.py", línea 401,
en send_header
11:13:11 web.1 | self.wfile.write ("% s:% s \ r \ n"% (palabra clave, valor))
11:13:11 web.1 | IOError: [Errno 32] Tubería rota

Por favor ayuda

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/pallets/werkzeug/issues/954#issuecomment -247243400,
o silenciar el hilo
https://github.com/notifications/unsubscribe-auth/AA6MZ6DNiRIfL91CLeYOoA70W9_nQQzGks5qqOCMgaJpZM4I58cy
.

Guiado por la reciente confirmación de corrección, pude solucionar este problema llamando a app.run con passthrough_errors = False. YMMV

El error que causó el bloqueo se corrigió en la versión 0.12 , lanzada el 21 de diciembre de 2016.

  • Revertir un cambio de comportamiento que hizo que el servidor de desarrollo se bloqueara en lugar de devolver un error interno del servidor (solicitud de extracción n. ° 2006).

La versión 0.12 se lanzó la semana pasada.

El lunes, 20 de marzo de 2017 a las 09:05:00 a. M. -0700, Alan Rotman escribió:

El error que causó el bloqueo se corrigió en la versión 0.12 , lanzada el 21 de diciembre de 2016.

  • Revertir un cambio de comportamiento que hizo que el servidor de desarrollo se bloqueara en lugar de devolver un error interno del servidor (solicitud de extracción n. ° 2006).

-
Recibe esto porque modificó el estado abierto / cerrado.
Responda a este correo electrónico directamente o véalo en GitHub:
https://github.com/pallets/werkzeug/issues/954#issuecomment -287807602

Acabo de ver ReleaseNotes hoy y he estado esperando esta solución durante mucho tiempo.

Mire: http://flask.pocoo.org/docs/0.12/changelog/
Versión 0.12
Publicado el 21 de diciembre de 2016, nombre en clave Punsch.

https://pypi.python.org/pypi/Flask/0.12
Tipo de archivo Py Version Uploaded on Size
Matraz-0.12-py2.py3-none-any.whl (md5) Python Wheel 2.7 2016-12-21 80KB
Flask-0.12.tar.gz (md5) Fuente 2016-12-21 519KB

Ah, sí, te refieres a Flask. Seguro.

El lunes 20 de marzo de 2017 a las 09:22:15 AM -0700, Alan Rotman escribió:

Acabo de ver ReleaseNotes hoy y he estado esperando esta solución durante mucho tiempo.

Mire: http://flask.pocoo.org/docs/0.12/changelog/
Versión 0.12
Publicado el 21 de diciembre de 2016, nombre en clave Punsch.

https://pypi.python.org/pypi/Flask/0.12
Tipo de archivo Py Version Uploaded on Size
Matraz-0.12-py2.py3-none-any.whl (md5) Python Wheel 2.7 2016-12-21 80KB
Flask-0.12.tar.gz (md5) Fuente 2016-12-21 519KB

-
Recibe esto porque modificó el estado abierto / cerrado.
Responda a este correo electrónico directamente o véalo en GitHub:
https://github.com/pallets/werkzeug/issues/954#issuecomment -287813405

Solo una nota para cualquiera que se encuentre con este problema al ejecutar el frasco 0.12.2 en werkzeug en modo subproceso = verdadero:
En el modo de subprocesos, por defecto, parece que cada subproceso de werkzeug todavía tiene este problema, es decir, si solicita una ruta que tarda algún tiempo en regresar y luego cierra la conexión del cliente, ese werkzeug en particular registra un IOError Broken Pipe y luego muere. El servidor en general continúa funcionando, excepto que en mi aplicación descubrí que esto estaba causando una pérdida de memoria de alguna manera, con el proceso del matraz creciendo lentamente después de una tubería rota en cualquier hilo, usando toda la RAM y luego SWAP y finalmente siendo asesinado por el sistema operativo.
El envío explícito de passthrough_errors = False en app.run parece haber resuelto el problema: los subprocesos ya no mueren cuando el cliente se desconecta, registran con gracia el IOError y luego también registran esto (que nunca vi sin establecer explícitamente passthrough_errors = False):

Exception happened during processing of request from ('127.0.0.1', 50652)
----------------------------------------

Y luego el servidor continúa funcionando normalmente. Todavía tengo que esperar unas horas para ver si la pérdida de memoria vuelve a aparecer, pero tengo la esperanza de que no.

Por si acaso eso es útil para alguien.

También vi este error en un contenedor de Ubuntu Docker en Kubernetes en Ubuntu VM:

Error on request:
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/werkzeug/serving.py", line 270, in run_wsgi
    execute(self.server.app)
  File "/usr/local/lib/python2.7/dist-packages/werkzeug/serving.py", line 261, in execute
    write(data)
  File "/usr/local/lib/python2.7/dist-packages/werkzeug/serving.py", line 227, in write
    self.send_header(key, value)
  File "/usr/lib/python2.7/BaseHTTPServer.py", line 412, in send_header
    self.wfile.write("%s: %s\r\n" % (keyword, value))
IOError: [Errno 32] Broken pipe

Creé una nueva máquina virtual Ubuntu xenial y ejecuté el mismo código en el contenedor de Ubuntu Docker en Kubernetes, y este error no se vio y Python Flask funcionó como se esperaba. Creo que fue un problema con mi host (Ubuntu VM).

@vhosakot ¿Puedes decirme cómo configuraste la configuración de tu aplicación? Encontré un problema similar en el mismo entorno que el suyo.

En una función de ruta, utilicé otra función que estaba destinada a enrutar.
Obtuve los datos de la respuesta de esa función.
Ahora, cuando usé _loads () _ en esos datos, aparece el error.

...
response = get_contents().data
        if response:
            data = loads(response)
..

Error: IOError: [Errno 32] Broken pipe

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