¿Cómo evitar la rotura de la tubería errno 32?

120

Actualmente estoy usando una aplicación construida en Python. Cuando lo ejecuto en una computadora personal, funciona sin problemas.

Sin embargo, cuando lo muevo a un servidor de producción. Sigue mostrándome el error adjunto de la siguiente manera:

He investigado un poco y tengo la razón por la que el navegador del usuario final detiene la conexión mientras el servidor todavía está ocupado enviando datos.

Me pregunto por qué sucedió y cuál es la causa raíz que impide que funcione correctamente en el servidor de producción, mientras funciona en mi computadora personal. Se agradece cualquier consejo

    Exception happened during processing of request from ('127.0.0.1', 34226)
Traceback (most recent call last):
  File "/usr/lib/python2.7/SocketServer.py", line 284, in
_handle_request_noblock
    self.process_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 310, in process_request
    self.finish_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 323, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/lib/python2.7/SocketServer.py", line 641, in __init__
    self.finish()
  File "/usr/lib/python2.7/SocketServer.py", line 694, in finish
    self.wfile.flush()
  File "/usr/lib/python2.7/socket.py", line 303, in flush
    self._sock.sendall(view[write_offset:write_offset+buffer_size])
error: [Errno 32] Broken pipe
SƲmmēr Aƥ
fuente
¿ Esto 'resuelve' su problema?
Pureferret
O conéctese con uwsgi, etc.
KyungHoon Kim

Respuestas:

85

El proceso de su servidor ha recibido una SIGPIPEescritura en un socket. Esto suele suceder cuando escribe en un socket completamente cerrado en el otro lado (cliente). Esto podría estar sucediendo cuando un programa cliente no espera hasta que se reciben todos los datos del servidor y simplemente cierra un socket (usando la closefunción).

En un programa C, normalmente intentaría configurar para ignorar la SIGPIPEseñal o configurar un manejador de señal ficticio para ella. En este caso, se devolverá un error simple al escribir en un socket cerrado. En su caso, una Python parece lanzar una excepción que puede manejarse como una desconexión prematura del cliente.

Maksim Skurydzin
fuente
2
Aquí hay una buena respuesta sobre el manejo de desconexiones de clientes: stackoverflow.com/a/180922/276274
Maksim Skurydzin
9

Depende de cómo lo haya probado y posiblemente de las diferencias en la implementación de la pila TCP de la computadora personal y el servidor.

Por ejemplo, si tu sendall siempre se completa inmediatamente (o muy rápidamente) en la computadora personal, es posible que la conexión nunca se haya interrumpido durante el envío. Esto es muy probable si su navegador se ejecuta en la misma máquina (ya que no hay una latencia de red real).


En general, solo necesita manejar el caso en el que un cliente se desconecta antes de que termine, manejando la excepción.

Recuerde que las comunicaciones TCP son asíncronas, pero esto es mucho más obvio en conexiones físicamente remotas que en las locales, por lo que condiciones como esta pueden ser difíciles de reproducir en una estación de trabajo local. Específicamente, las conexiones de bucle invertido en una sola máquina suelen ser casi sincrónicas.

Inútil
fuente
Lo estoy probando ejecutando "paster serve abc.ini --reload", sin embargo, nunca se pudo acceder a la página web. Y para la estación de trabajo VMWare, estoy usando la opción de solo host para la conexión de red. Entonces, ¿puede aconsejarme alguna forma de ejecutarlo correctamente?
SƲmmēr Aƥ
1
Creo que es una pregunta de configuración de red de VMWare separada (me temo que no sé nada al respecto). Sin embargo, la razón por la que la estación de trabajo y el servidor pueden comportarse de manera diferente es la anterior, y la solución es solo manejar la excepción contry ... except
inútil
7

El error de tubería rota generalmente ocurre si su solicitud está bloqueada o toma demasiado tiempo y después del tiempo de espera del lado de la solicitud, cerrará la conexión y luego, cuando el lado de respuesta (servidor) intente escribir en el socket, lanzará un Error de tubería rota.

Aaren Shar
fuente
3

Esto puede deberse a que está utilizando dos métodos para insertar datos en la base de datos y esto hace que el sitio se ralentice.

def add_subscriber(request, email=None):
    if request.method == 'POST':
        email = request.POST['email_field']
        e = Subscriber.objects.create(email=email).save()  <==== 
        return HttpResponseRedirect('/')
    else:
        return HttpResponseRedirect('/')

En la función anterior, el error es donde apunta la flecha. La implementación correcta está a continuación:

def add_subscriber(request, email=None):
    if request.method == 'POST':
        email = request.POST['email_field']
        e = Subscriber.objects.create(email=email)
        return HttpResponseRedirect('/')
    else:
        return HttpResponseRedirect('/')
Kuldeep K. Rishi
fuente