Werkzeug: Werkzeug plante après avoir écrit sur un tuyau fermé

Créé le 20 juin 2016  ·  41Commentaires  ·  Source: pallets/werkzeug

J'ai un serveur Werkzeug fonctionnant derrière NGINX. Lorsqu'un client se déconnecte en attendant que le serveur Werkzeug réponde, NGINX ferme le canal vers Werkzeug. Lorsque le programme python écrit la réponse à Werkzeug, l'exception suivante se produit et Werkzeug se bloque :

Traceback (appel le plus récent en dernier) :
Fichier "server.py", ligne 81, dans
app.run(host=args.host, port=args.port, debug=False)
Fichier "/usr/local/lib/python2.7/dist-packages/flask/app.py", ligne 843, en cours d'exécution
run_simple(hôte, port, self, **options)
Fichier "/usr/local/lib/python2.7/dist-packages/werkzeug/serving.py", ligne 694, dans run_simple
intérieur()
Fichier "/usr/local/lib/python2.7/dist-packages/werkzeug/serving.py", ligne 659, dans
srv.serve_forever()
Fichier "/usr/local/lib/python2.7/dist-packages/werkzeug/serving.py", ligne 499, dans serve_forever
HTTPServer.serve_forever(self)
Fichier "/usr/lib/python2.7/SocketServer.py", ligne 238, dans serve_forever
self._handle_request_noblock()
Fichier "/usr/lib/python2.7/SocketServer.py", ligne 297, dans _handle_request_noblock
self.handle_error(request, client_address)
Fichier "/usr/lib/python2.7/SocketServer.py", ligne 295, dans _handle_request_noblock
self.process_request(request, client_address)
Fichier "/usr/lib/python2.7/SocketServer.py", ligne 321, dans process_request
self.finish_request(request, client_address)
Fichier "/usr/lib/python2.7/SocketServer.py", ligne 334, dans finish_request
self.RequestHandlerClass(request, client_address, self)
Fichier "/usr/lib/python2.7/SocketServer.py", ligne 651, dans init
self.finish()
Fichier "/usr/lib/python2.7/SocketServer.py", ligne 710, en finition
self.wfile.close()
Fichier "/usr/lib/python2.7/socket.py", ligne 279, en fin
self.flush()
Fichier "/usr/lib/python2.7/socket.py", ligne 303, en flush
self._sock.sendall(view[write_offset:write_offset+buffer_size])
socket.error : [Errno 32] Tuyau cassé

Y a-t-il une option de configuration qui me manque pour l'empêcher de planter? Normalement, toutes les exceptions sont interceptées et une erreur 500 est renvoyée, le serveur restant actif.

Commentaire le plus utile

Guidé par le récent commit de correctif, j'ai pu résoudre ce problème en appelant app.run avec passthrough_errors=False. YMMV

Tous les 41 commentaires

Utilisez un serveur WSGI de production tel que Gunicorn ou uWSGI, et non le serveur de développement Werkzeug.

J'ai un problème très similaire sauf que j'utilise le serveur de développement Werkzeug pour le développement (qui est, AFAICT, son utilisation prévue), c'est-à-dire avec le navigateur directement connecté au port 5000.

L'erreur se produit plusieurs fois par heure, forçant un redémarrage manuel du serveur pour continuer à se développer.

Voici une trace :

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

Je rencontre le même problème que @sfermigier avec le serveur de développement ( debug=True ), et j'ai la même erreur de traçabilité.

Ce comportement se produit généralement dans un cas très simple : vous utilisez une sorte de fonctionnalités de saisie semi-automatique. Le navigateur démarre une connexion pour les jetons de requête, puis s'arrête et démarre une autre demande pour d'autres jetons. Vous vous retrouverez avec beaucoup de tuyaux cassés. Et ce n'était pas un problème jusqu'à la dernière version, ce qui bloque complètement le serveur de développement.
Donc, suggérer d'utiliser un serveur d'applications complet est une bonne solution de contournement, mais je vois toujours un problème ici. Un problème de développement bien sûr, mais le fait qu'il soit si courant de déclencher le rend perturbant pour de nombreux développeurs non habitués aux _protocoles internes_.
Un tuyau cassé est très courant (pensez à une longue requête par erreur et au développeur appuyant sur le bouton d'arrêt du navigateur) et ne devrait pas casser le serveur de développement.
Juste mon avis. :)

@xcash

Ce comportement se produit généralement dans un cas très simple : vous utilisez une sorte de fonctionnalités de saisie semi-automatique. Le navigateur démarre une connexion pour les jetons de requête, puis s'arrête et démarre une autre demande pour d'autres jetons.

Si c'est lié, je peux confirmer que je rencontre ce problème en utilisant browsersync avec gulp.js .

Quelqu'un a-t-il une solution qui n'inclut pas l'exécution d'un serveur WSGI ? Je semble rencontrer ce problème avec des robots effectuant une analyse SYN contre mon hôte.

@glenzw peux-tu être plus précis sur ton environnement ? Vous ne devriez pas rendre votre serveur de développement public sur le Web ouvert accessible par les bots. :) Dans une telle situation, comme un hébergeur de démonstration pour les clients, il est toujours préférable d'utiliser au moins un vrai serveur d'applications comme gunicorn qui a un très faible encombrement.

FWIW, je n'ai pas beaucoup suivi les versions et ce problème (très ennuyeux) a commencé à se produire pour moi entre mai et août 2016, du mieux que je sache. J'ai ajouté ceci à mon setup.py install_requires = ['Werkzeug<0.11', 'flask<0.11', ... - ce qui semble contourner le problème (IME, le simple fait d'épingler Werkzeug n'a pas semblé faire l'affaire ?)

Pour moi, le cas de duplication était assez simple - chargez une page, mais ne la laissez pas finir de se charger. C'est-à-dire qu'il suffit de déclencher _tout_ une erreur de tuyau cassé - et le serveur Web se bloquera et ne pourra pas répondre à d'autres requêtes. À mon humble avis, les serveurs Web ne peuvent pas _tomber_ lorsqu'un client ferme la connexion prématurément - même ceux de développement.

Se pourrait-il que vous ayez tous défini passthrough_errors quelque part ?

@untitaker dans ce cas, palettes/flacon#1674 palettes/flacon#1679 palettes/flacon#1928 peut-être lié ?

Je ne sais pas, j'aimerais que l'un des journalistes me confirme.

Le 26 août 2016 à 17:05:25 CEST, David Lord [email protected] a écrit :

@untitaker dans ce cas, palettes/flacon#1674 palettes/flacon#1679
palettes/flacon n°1928 peut-être lié ?

Vous recevez ceci parce que vous avez été mentionné.
Répondez directement à cet e-mail ou consultez-le sur GitHub :
https://github.com/pallets/werkzeug/issues/954#issuecomment-242761250

Envoyé depuis mon appareil Android avec K-9 Mail. Veuillez excuser ma brièveté.

cc @miguelgrinberg

Je pense que Werkzeug devrait gérer les erreurs de réinitialisation de tuyau et de connexion cassées. Ce ne sont vraiment pas une indication d'une erreur, le client vient de s'en aller. Il semble que dans ce cas, une exception spéciale devrait être levée, une exception reconnue par le fourre-tout ci-dessus comme une exception à ignorer, même si le transfert d'erreur est défini.

Voici comment fait gunicorn : https://github.com/benoitc/gunicorn/blob/39f62ac66beaf83ceccefbfabd5e3af7735d2aff/gunicorn/workers/sync.py#L151 -L154

C'est ce qu'il est censé faire. J'essaye de comprendre comment reproduire
ce comportement, mais il n'y a pas encore de scénario de test clair disponible. D'où la question
environ passthrough_errors .

Je soupçonne que ce n'est pas un bogue dans Werkzeug, et que le navigateur de l'utilisateur
a simplement une connexion encore ouverte qui bloque les autres requêtes (au lieu de la
plantage du serveur). Si vous fermez votre navigateur et le rouvrez, le serveur devrait
fonctionner à nouveau.

Le vendredi 26 août 2016 à 11:54:16 -0700, Miguel Grinberg a écrit :

Je pense que Werkzeug devrait gérer les erreurs de réinitialisation de tuyau et de connexion cassées. Ce ne sont vraiment pas une indication d'une erreur, le client vient de s'en aller. Il semble que dans ce cas, une exception spéciale devrait être levée, une exception reconnue par le fourre-tout ci-dessus comme une exception à ignorer, même si le transfert d'erreur est défini.

Voici comment fait gunicorn : https://github.com/benoitc/gunicorn/blob/39f62ac66beaf83ceccefbfabd5e3af7735d2aff/gunicorn/workers/sync.py#L151 -L154

Vous recevez ceci parce que vous avez été mentionné.
Répondez directement à cet e-mail ou consultez-le sur GitHub :
https://github.com/pallets/werkzeug/issues/954#issuecomment-242821084

Oh, et les erreurs de tuyau cassé _sont_ affichées, oui, mais elles ne devraient jamais raccrocher le serveur comme décrit. Voir le commentaire précédent sur la raison possible.

J'ai retesté les derniers bits et je constate toujours le même comportement dans mon environnement. Mais comme vous sembliez avoir du mal à vous reproduire, j'ai essayé de comprendre pourquoi je suis spécial.

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

Cela fonctionne comme prévu avec flask run mais le serveur Web planterait si vous fermez votre navigateur Web avant de laisser la réponse s'afficher au démarrage via python hello.py

Il semble qu'une partie de votre réponse soit perdue.

Le vendredi 26 août 2016 à 12:29:39 -0700, clayg a écrit :

J'ai retesté les derniers bits et je constate toujours le même comportement dans mon environnement. Mais comme vous sembliez avoir du mal à vous reproduire, j'ai essayé de comprendre pourquoi je suis spécial.

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

oui, en slack triple-ticks est la façon dont vous bloquez la citation et ctrl-return est la façon dont vous changez de ligne
sur github, triple-ticks est la façon dont vous bloquez le devis, mais ctrl-return est la façon dont vous soumettez
... de toute façon ... la mémoire musculaire

J'ai modifié mon message immédiatement après l'avoir soumis pour terminer - et je ne réponds que parce qu'il semble que vous répondiez par e-mail et je ne suis pas sûr que github vous enverra un autre avis après ma modification.

Je ne peux pas reproduire avec le test de sommeil de @clayg ci-dessus. En fait, je n'obtiens pas du tout l'erreur de tuyau cassé. Je ferme le navigateur avant que cette demande ne renvoie une réponse, mais Werkzeug exécute la demande jusqu'à la fin de toute façon, il imprime la ligne de journal 200 sur la console et ne montre aucune erreur.

J'ai également essayé la même astuce en utilisant mon exemple de streaming vidéo flask qui utilise une réponse de streaming pour fournir des images vidéo dans un flux sans fin, et même pour celui-ci, je peux fermer le navigateur et la demande se termine sans aucune erreur. Celui-ci est étrange, car je suis certain que dans le passé, cette application déclenchait une erreur de tuyau cassé vers la console avant de mettre fin à la demande.

En fait, j'ai parlé trop tôt. Je peux reproduire à chaque fois avec mon application de streaming vidéo lorsque j'utilise Python 2.7. Je ne peux pas reproduire sur 3.5. Toutes les traces de pile ci-dessus sont pour 2.7, alors gardez cela à l'esprit si vous testez avec Python 3.

Un autre point de données intéressant. En cas d'exécution avec le rechargeur, lorsque le processus enfant se termine, le processus maître exécutant le rechargeur en démarre un autre, il n'y a donc pas d'interruption. Mais si vous exécutez le serveur sans le rechargeur, l'erreur de tuyau cassé vous ramène à la console.

Edit: ne tenez pas compte du rechargement qui démarre une autre partie du processus, cela ne semble pas se produire et à la place, je voyais probablement l'effet de la modification du paramètre d'erreur de passthrough.

Bon, voici l'analyse de ce que je pense qui se passe:

  • Le client s'en va à mi-demande
  • La demande continue. La connexion socket semble être mise en mémoire tampon, donc dans la plupart des cas, les écritures sur le socket ne causeront aucun problème.
  • Une fois la requête terminée, la classe du serveur de socket émettra un flush() sur le socket. Cela faisait l'objet d'un ancien bogue dans la bibliothèque Python qui est actuellement corrigé : http://bugs.python.org/issue14574. La solution dans ce correctif était d'attraper socket.error et de l'ignorer.
  • Ensuite, le serveur de socket essaie de fermer la connexion. Il s'agit du cadre de pile suivant, à partir du backtrace de l'OP :

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

  • Malheureusement, dans Python 2.7, la première chose que fait la méthode socket.close() est de rincer à nouveau :

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

  • Cette deuxième tentative de vidage n'est pas protégée par un try/except, elle lève donc l'exception EPIPE.
  • Le serveur de socket intercepte l'exception, puis la transmet à la méthode handle_error() du serveur.
  • L'implémentation Werkzeug de handle_error() examine le paramètre passthrough_errors , et puisque nous l'avons toujours défini sur True , relance l'erreur EPIPE et la laisse remonter jusqu'au Haut.

Le code de socket sur Python 3 est complètement différent, et en particulier, il ne semble pas avoir d'appels flush sans try/excepts autour d'eux. L'erreur EPIPE ne remonte même pas à Werkzeug lors de l'utilisation de Python 3.

Avons-nous même passthrough_errors défini sur true ? Dans Werkzeug, il est faux par défaut.

Le 27 août 2016 02:10:13 CEST, Miguel Grinberg [email protected] a écrit :

Bon, voici l'analyse de ce que je pense qui se passe:

  • Le client s'en va à mi-demande
  • La demande continue. La connexion de la prise semble être
    mis en mémoire tampon, donc dans la plupart des cas, les écritures sur le socket ne provoqueront aucun
    problèmes.
  • Une fois la requête terminée, la classe du serveur de socket émettra un flush()
    sur la prise. C'était l'objet d'un ancien bug dans la bibliothèque Python
    qui est actuellement corrigé : http://bugs.python.org/issue14574. Les
    la solution dans ce correctif était d'attraper socket.error et de l'ignorer.
  • Ensuite, le serveur de socket essaie de fermer la connexion. C'est le
    cadre de pile suivant, à partir du backtrace de l'OP :
 File "/usr/lib/python2.7/SocketServer.py", line 710, in finish
 self.wfile.close()

  • Malheureusement, dans Python 2.7, la première chose que le socket.close()
    la méthode est à nouveau vide :
 File "/usr/lib/python2.7/socket.py", line 279, in close
 self.flush()

  • Cette deuxième tentative de flush n'est pas protégée par un try/except, donc
    il lève l'exception EPIPE.
  • Le serveur de socket intercepte l'exception, puis la transmet au
    méthode handle_error() du serveur.
  • L'implémentation Werkzeug de handle_error() examine le
    passthrough_errors , et puisque nous l'avons toujours défini sur
    True , relance l'erreur EPIPE et la laisse remonter vers le haut.

Le code socket sur Python 3 est complètement différent, et en particulier,
il ne semble pas avoir d'appels flush sans try/excepts autour
eux. L'erreur EPIPE ne remonte même pas à Werkzeug lors de l'utilisation
Python3.

Vous recevez ceci parce que vous avez été mentionné.
Répondez directement à cet e-mail ou consultez-le sur GitHub :
https://github.com/pallets/werkzeug/issues/954#issuecomment-242881523

Envoyé depuis mon appareil Android avec K-9 Mail. Veuillez excuser ma brièveté.

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

Je pense que passthrough_errors devrait dépendre de app.debug . NVM, est inutile

Je ne vois pas d'autre option que de revenir sur ce PR en fait. passthrough_errors=True juste ce qu'il est censé faire, ce qui n'est pas un bon comportement par défaut si l'on n'a pas attaché de débogueur au programme.

Tant pis, j'ai trouvé un autre moyen. Deux PR :

Étant donné que les deux sont des changements de comportement au sens large, je préfère ne pas les rétroporter.

Je pense que https://github.com/pallets/flask/pull/1996 est une solution acceptable. L'important est qu'il corrige le cas courant où vous ne voulez pas que les exceptions se propagent. Si vous voulez propager, alors vous déboguez, et dans ce cas, obtenir le socket.error propagé alors qu'il ne devrait pas n'est pas un gros problème.

Le correctif https://github.com/pallets/werkzeug/pull/998 n'est cependant pas génial. L'application pourrait lever ces exceptions légitimement à partir de quelque chose qu'elle fait avec des sockets dans ses propres gestionnaires, et celles-ci seraient également réduites au silence. La solution idéale serait que ceux-ci soient interceptés à l'endroit où ils se produisent, puis relancés en tant que classe d'exception personnalisée que handle_error peut reconnaître et ignorer. Étant donné que nous ne voulons probablement pas modifier ou surcharger SocketServer , je pense que mon vote est de laisser cette partie telle quelle. Vous obtiendrez l'EPIPE déversé sur la console, mais uniquement sur Python 2, et au moins cela n'arrêtera pas le serveur après l'entrée de l'autre correctif. C'est inoffensif, et c'est un comportement qui existait dans le passé, avant que je fasse le passthrough_errors changement.

Le comportement que vous décrivez ne se produit cependant qu'avec PASSTHROUGH_ERRORS activé. Sinon, l'exception est interceptée depuis Flask.

Je suppose que cette amélioration cosmétique n'en vaut pas la peine.

Le 27 août 2016 à 18:29:30 CEST, Miguel Grinberg [email protected] a écrit :

Je pense que https://github.com/pallets/flask/pull/1996 est un acceptable
Solution. L'important est qu'il corrige le cas courant où
vous ne voulez pas que les exceptions se propagent. Si vous voulez propager,
alors vous déboguez, et dans ce cas vous obtenez le socket.error
propagé alors qu'il ne devrait pas n'est pas une grosse affaire.

Le correctif https://github.com/pallets/werkzeug/pull/998 n'est pas génial
bien que. L'application pourrait soulever ces exceptions légitimement de
quelque chose qu'il fait avec des sockets dans ses propres gestionnaires, et ceux-ci seraient
être également réduit au silence. La solution idéale serait que ceux-ci soient pris
à l'endroit où ils se produisent, puis sur-relevés en tant qu'exception personnalisée
classe que handle_error peut reconnaître et ignorer. Étant donné que nous
ne veux probablement pas changer ou surcharger SocketServer , je pense que mon
vote est de laisser cette partie telle quelle. Vous obtiendrez l'EPIPE sous-évalué à
la console, mais uniquement sur Python 2, et au moins ça ne va pas s'arrêter
le serveur après l'entrée de l'autre correctif. C'est inoffensif, et c'est un
comportement qui existait dans le passé, avant que je
passthrough_errors changement.

Vous recevez ceci parce que vous avez été mentionné.
Répondez directement à cet e-mail ou consultez-le sur GitHub :
https://github.com/pallets/werkzeug/issues/954#issuecomment-242926832

Envoyé depuis mon appareil Android avec K-9 Mail. Veuillez excuser ma brièveté.

Corrigé dans le maître.

Le comportement que vous décrivez ne se produit qu'avec PASSTHROUGH_ERRORS activé cependant

Oui, j'ai omis ce détail. Mais ce changement affecterait même Python 3, où rien de tout cela n'est un problème. Sur Py3, avec les erreurs passthrough activées, une socket.error légitime déclenchée par l'application serait réduite au silence.

maître semble wfm, dans l'attente de la prochaine version, merci!

Salut, j'utilise un serveur de développement Werkzeug fonctionnant derrière NGINX, je suis confronté au même problème, quelqu'un pourrait-il m'aider avec cela,
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

S'il vous plaît aider

Ragav utilise un autre serveur d'applications au lieu du dev intégré de werkzeug
serveur, comme gunicorn. C'est la seule solution pour le moment.

2016-09-15 08:07 GMT-02: Ragav [email protected] :

Salut, j'utilise un serveur de développement Werkzeug fonctionnant derrière NGINX, je suis confronté au
même problème, quelqu'un pourrait-il m'aider, ```
11:13:11 web.1 | 127.0.0.1 - - [15/Sep/2016 11:13:11] "OBTENIR
/api/method/frappe.utils.print_format.download_pdf?
doctype=Achat%20Commande&name=PO-00001&format=PO&no_letterhead=0
HTTP/1.1" 200 -
11:13:11 web.1 | Erreur sur demande :
11:13:11 web.1 | Traceback (appel le plus récent en dernier) :
11:13:11 web.1 | Fichier "/home/ommi/frappe-bench/env/
lib/python2.7/site-packages/werkzeug/serving.py", ligne 193, dans run_wsgi
11:13:11 web.1 | exécuter(self.server.app)
11:13:11 web.1 | Fichier "/home/ommi/frappe-bench/env/
lib/python2.7/site-packages/werkzeug/serving.py", ligne 184, en exécution
11:13:11 web.1 | écrire (données)
11:13:11 web.1 | Fichier "/home/ommi/frappe-bench/env/
lib/python2.7/site-packages/werkzeug/serving.py", ligne 152, en écriture
11:13:11 web.1 | self.send_header(clé, valeur)
11:13:11 web.1 | Fichier "/usr/lib/python2.7/BaseHTTPServer.py", ligne 401,
dans send_header
11:13:11 web.1 | self.wfile.write("%s : %s\r\n" % (mot-clé, valeur))
11:13:11 web.1 | IOError : [Errno 32] Tuyau cassé

S'il vous plaît aider

-
Vous recevez ceci parce que vous avez été mentionné.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/pallets/werkzeug/issues/954#issuecomment-247243400 ,
ou couper le fil
https://github.com/notifications/unsubscribe-auth/AA6MZ6DNiRIfL91CLeYOoA70W9_nQQzGks5qqOCMgaJpZM4I58cy
.

Guidé par le récent commit de correctif, j'ai pu résoudre ce problème en appelant app.run avec passthrough_errors=False. YMMV

Le bogue qui a causé le plantage a été corrigé dans la version 0.12 , publiée le 21 décembre 2016.

  • Annulez un changement de comportement qui a fait planter le serveur de développement au lieu de renvoyer une erreur de serveur interne (pull request #2006).

La version 0.12 n'est sortie que la semaine dernière.

Le lundi 20 mars 2017 à 09:05:00 -0700, Alan Rotman a écrit :

Le bogue qui a causé le plantage a été corrigé dans la version 0.12 , publiée le 21 décembre 2016.

  • Annulez un changement de comportement qui a fait planter le serveur de développement au lieu de renvoyer une erreur de serveur interne (pull request #2006).

--
Vous recevez ceci parce que vous avez modifié l'état ouvert/fermé.
Répondez directement à cet e-mail ou consultez-le sur GitHub :
https://github.com/pallets/werkzeug/issues/954#issuecomment -287807602

Je viens de voir ReleaseNotes aujourd'hui et j'attends ce correctif depuis longtemps.

Regardez : http://flask.pocoo.org/docs/0.12/changelog/
Version 0.12
Sorti le 21 décembre 2016, nom de code Punsch.

https://pypi.python.org/pypi/Flask/0.12
Type de fichier Py Version téléchargée sur la taille
Flask-0.12-py2.py3-none-any.whl (md5) Roue Python 2.7 2016-12-21 80KB
Flacon-0.12.tar.gz (md5) Source 2016-12-21 519KB

Ah, oui, tu veux dire Flask. Sûr.

Le lundi 20 mars 2017 à 09:22:15 -0700, Alan Rotman a écrit :

Je viens de voir ReleaseNotes aujourd'hui et j'attends ce correctif depuis longtemps.

Regardez : http://flask.pocoo.org/docs/0.12/changelog/
Version 0.12
Sorti le 21 décembre 2016, nom de code Punsch.

https://pypi.python.org/pypi/Flask/0.12
Type de fichier Py Version téléchargée sur la taille
Flask-0.12-py2.py3-none-any.whl (md5) Roue Python 2.7 2016-12-21 80KB
Flacon-0.12.tar.gz (md5) Source 2016-12-21 519KB

--
Vous recevez ceci parce que vous avez modifié l'état ouvert/fermé.
Répondez directement à cet e-mail ou consultez-le sur GitHub :
https://github.com/pallets/werkzeug/issues/954#issuecomment -287813405

Juste une note pour tous ceux qui rencontrent ce problème lors de l'exécution du flacon 0.12.2 sur werkzeug en mode threaded=True :
En mode threadé, par défaut, il semble que chaque thread werkzeug ait toujours ce problème, c'est-à-dire que si vous demandez une route qui prend un certain temps à revenir, puis fermez la connexion du client, ce werkzeug particulier enregistre une IOError Broken Pipe puis meurt. Le serveur dans son ensemble continue de fonctionner, sauf que dans mon application, je trouvais que cela provoquait une fuite de mémoire d'une manière ou d'une autre, le processus de flacon se développant lentement après un tuyau cassé dans n'importe quel thread, utilisant toute la RAM, puis SWAP et enfin étant tué par le système d'exploitation.
L'envoi explicite de passthrough_errors=False dans app.run semble avoir résolu le problème - les threads ne meurent plus lorsque le client se déconnecte, ils enregistrent gracieusement l'IOError, puis enregistrent également ceci (que je n'ai jamais vu sans définir explicitement passthrough_errors=False) :

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

Et puis le serveur continue de fonctionner normalement. Je dois encore attendre quelques heures pour voir si la fuite de mémoire réapparaît, mais j'espère que ce ne sera pas le cas.

Juste au cas où cela serait utile à quelqu'un.

J'ai également vu cette erreur dans un conteneur Ubuntu Docker sur Kubernetes sur 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

J'ai créé une toute nouvelle machine virtuelle Ubuntu xenial et exécuté le même code dans le conteneur Ubuntu Docker sur Kubernetes, et cette erreur n'a pas été vue et Python Flask a fonctionné comme prévu. Je pense que c'était un problème avec mon hôte (Ubuntu VM).

@vhosakot Pouvez-vous me dire comment vous avez configuré la configuration de votre application ? J'ai rencontré un problème similaire dans le même environnement que le vôtre.

Dans une fonction de routage, j'ai utilisé une autre fonction destinée au routage.
J'ai récupéré les données de la réponse de cette fonction.
Maintenant, lorsque j'ai utilisé _loads()_ sur ces données, j'obtiens l'erreur.

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

Erreur : IOError: [Errno 32] Broken pipe

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

golf-player picture golf-player  ·  10Commentaires

asottile picture asottile  ·  11Commentaires

davidism picture davidism  ·  9Commentaires

androiddrew picture androiddrew  ·  14Commentaires

abathur picture abathur  ·  13Commentaires