L’erreur “broken pipe” avec les serveurs Python tel Gunicorn


Quand on commence à avoir pas mal de trafic sur son site, on commence à noter l’apparition d’une erreur inquiétante :

Traceback (most recent call last):
File "gunicorn/workers/async.py", line 44, in handle
self.handle_request(req, client, addr)
File "gunicorn/workers/ggevent.py", line 88, in handle_request
super(GeventWorker, self).handle_request(*args)
File "gunicorn/workers/async.py", line 83, in handle_request
resp.write(item)
File "gunicorn/http/wsgi.py", line 275, in write
util.write(self.sock, arg, self.chunked)
File "gunicorn/util.py", line 232, in write
sock.sendall(data)
File "gevent/socket.py", line 480, in sendall
data_sent += self.send(_get_memory(data, data_sent), flags)
File "gevent/socket.py", line 451, in send
return sock.send(data, flags)
error: [Errno 32] Broken pipe

Et plus il y a de trafic, plus cette erreur apparait dans les logs.

Pourtant, impossible de trouver la cause de l’erreur, tout semble bien marcher, le serveur pète la forme et ipdb ne donne rien du tout.

La raison pour laquelle vous ne trouvez rien, c’est qu’il n’y a rien à trouver. Cette erreur est levée par le module socket quand il essaye d’écrire sur une connexion qui s’est fermée brutalement.

Or le serveur ne peut pas savoir quand une connexion s’est fermée si le client ne lui envoie pas le message. Et il peut y avoir énormément de raisons pour que ça arrive : fermeture d’un onglet en plein chargement, crash du navigateur, extinction du PC pendant la réponse, etc.

Vous en voyez plus quand le trafic augmente tout simplement parce que statistiquement, avec plus de visiteurs, ces situations rares se rencontrent plus facilement dans la masse de connexions.

Donc pour l’erreur “broken pipe”, il n’y a rien à faire, à part de monter le log level de votre serveur d’un cran pour qu’il n’affiche plus ça dans vos logs.

Des questions Python sans rapport avec l'article ? Posez-les sur IndexError.