How to prevent errno 32 broken pipe?
Asked Answered
W

7

185

Currently I am using an app built in python. When I run it in personal computer, it works without problems.

However, when I move it into a production server. It keeps showing me the error attached as below:.

I've done some research and I got the reason that the end user browser stops the connection while the server is still busy sending data.

I wonder why did it happen and what is the root cause that prevents it from running properly in production server, while it works on my personal computer. Any advice is appreciated

    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
Whisky answered 8/8, 2012 at 14:31 Comment(2)
Does this 'solve' your issue?Wingfooted
Or connect with uwsgi, etc.Unpin
C
120

Your server process has received a SIGPIPE writing to a socket. This usually happens when you write to a socket fully closed on the other (client) side. This might be happening when a client program doesn't wait till all the data from the server is received and simply closes a socket (using close function).

In a C program you would normally try setting to ignore SIGPIPE signal or setting a dummy signal handler for it. In this case a simple error will be returned when writing to a closed socket. In your case a python seems to throw an exception that can be handled as a premature disconnect of the client.

Cylinder answered 8/8, 2012 at 14:40 Comment(1)
Here is a good answer regarding handling client disconnects: https://mcmap.net/q/137437/-how-to-handle-a-broken-pipe-sigpipe-in-pythonCylinder
S
25

The broken pipe error usually occurs if your request is blocked or takes too long and after request-side timeout, it'll close the connection and then, when the respond-side (server) tries to write to the socket, it will throw a pipe broken error.

Spline answered 20/1, 2015 at 8:12 Comment(1)
yes e.g. I wanted to upload too much data on Google Sheets with 1 request. After halving the dataset, it worked.Slowworm
A
10

It depends on how you tested it, and possibly on differences in the TCP stack implementation of the personal computer and the server.

For example, if your sendall always completes immediately (or very quickly) on the personal computer, the connection may simply never have broken during sending. This is very likely if your browser is running on the same machine (since there is no real network latency).


In general, you just need to handle the case where a client disconnects before you're finished, by handling the exception.

Remember that TCP communications are asynchronous, but this is much more obvious on physically remote connections than on local ones, so conditions like this can be hard to reproduce on a local workstation. Specifically, loopback connections on a single machine are often almost synchronous.

Aloes answered 8/8, 2012 at 14:39 Comment(2)
I am testing it by running "paster serve abc.ini --reload", however the webpage could never be reached. And for the VMWare Workstation, I am using Host-only option for network connection. So can you kindly advise any way to run it properly?Descent
I think that's a seperate VMWare network config question (I'm afraid I don't know anything about that). The reason the workstation and server may behave differently is above though, and the solution is just to handle the exception with try ... exceptAloes
S
3

This might be because you are using two method for inserting data into database and this cause the site to slow down.

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('/')

In above function, the error is where arrow is pointing. The correct implementation is below:

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('/')
Scalage answered 17/1, 2014 at 11:16 Comment(0)
M
3

Try this code at the top of your program:

from signal import signal, SIGPIPE, SIG_DFL
signal(SIGPIPE,SIG_DFL)

It should fix the issue.

Mutiny answered 25/10, 2022 at 16:40 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Ludivinaludlew
P
0

If it's a python a web application or service such as Flask or FastAPI, this error might occur if the production server is configured to timeout a request that takes too long. There are relevant parameters in Gunicorn and Uvicorn such as GRACEFUL_TIMEOUT and TIMEOUT that need to be configured according to the needs of your application. You may also want to check your reverse proxy or gateway timeout thresholds.

Pizarro answered 22/6, 2021 at 19:36 Comment(0)
S
0

Try this code in you main file:

def signal_handler(signal, frame):
      # Perform cleanup tasks here
      print("Ctrl+C pressed. Cleaning up and exiting...")

      ack_sock.close()
      perf_sock.close()
      sys.exit(0)


if __name__ == '__main__':
   # Register the signal handler
   signal.signal(signal.SIGINT, signal_handler)
   signal.signal(signal.SIGPIPE, signal_handler)
Soiree answered 21/3 at 12:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.