Werkzeug: Werkzeug stürzt ab, nachdem in ein geschlossenes Rohr geschrieben wurde

Erstellt am 20. Juni 2016  ·  41Kommentare  ·  Quelle: pallets/werkzeug

Ich habe einen Werkzeug-Server, der hinter NGINX läuft. Wenn ein Client die Verbindung trennt, während er auf die Antwort des Werkzeug-Servers wartet, schließt NGINX die Leitung zum Werkzeug. Wenn das Python-Programm die Antwort an Werkzeug schreibt, tritt die folgende Ausnahme auf und Werkzeug stürzt ab:

Traceback (letzter Anruf zuletzt):
Datei "server.py", Zeile 81, in
app.run(host=args.host, port=args.port, debug=False)
Datei "/usr/local/lib/python2.7/dist-packages/flask/app.py", Zeile 843, in Run
run_simple(Host, Port, selbst, **Optionen)
Datei "/usr/local/lib/python2.7/dist-packages/werkzeug/serving.py", Zeile 694, in run_simple
innere()
Datei "/usr/local/lib/python2.7/dist-packages/werkzeug/serving.py", Zeile 659, in inner
srv.serve_forever()
Datei "/usr/local/lib/python2.7/dist-packages/werkzeug/serving.py", Zeile 499, in serve_forever
HTTPServer.serve_forever(self)
Datei "/usr/lib/python2.7/SocketServer.py", Zeile 238, in serve_forever
self._handle_request_noblock()
Datei "/usr/lib/python2.7/SocketServer.py", Zeile 297, in _handle_request_noblock
self.handle_error(request, client_address)
Datei "/usr/lib/python2.7/SocketServer.py", Zeile 295, in _handle_request_noblock
self.process_request(request, client_address)
Datei "/usr/lib/python2.7/SocketServer.py", Zeile 321 in process_request
self.finish_request(request, client_address)
Datei "/usr/lib/python2.7/SocketServer.py", Zeile 334, in finish_request
self.RequestHandlerClass(request, client_address, self)
Datei "/usr/lib/python2.7/SocketServer.py", Zeile 651, in init
self.finish()
Datei "/usr/lib/python2.7/SocketServer.py", Zeile 710, im Finish
self.wfile.close()
Datei "/usr/lib/python2.7/socket.py", Zeile 279, in Close
self.flush()
Datei "/usr/lib/python2.7/socket.py", Zeile 303, in flush
self._sock.sendall(view[write_offset:write_offset+buffer_size])
socket.error: [Errno 32] Rohrbruch

Gibt es eine Konfigurationsoption, die mir fehlt, damit es nicht abstürzt? Normalerweise werden alle Ausnahmen abgefangen und ein 500-Fehler zurückgegeben, wobei der Server am Leben bleibt.

Hilfreichster Kommentar

Geleitet vom letzten Fix-Commit konnte ich dieses Problem beheben, indem ich app.run mit passthrough_errors=False aufrief. YMMV

Alle 41 Kommentare

Verwenden Sie einen Produktions-WSGI-Server wie Gunicorn oder uWSGI, nicht den Werkzeug-Entwicklungsserver.

Ich habe ein sehr ähnliches Problem, außer dass ich den Werkzeug-Entwicklungsserver für die Entwicklung verwende (das heißt AFAICT, seine beabsichtigte Verwendung), dh mit dem Browser, der direkt mit Port 5000 verbunden ist.

Der Fehler tritt mehrmals pro Stunde auf und erzwingt einen manuellen Neustart des Servers, um sich weiterzuentwickeln.

Hier ist eine Rückverfolgung:

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

Ich habe das gleiche Problem wie @sfermigier mit dem Entwicklungsserver ( debug=True ) und habe den gleichen Traceback-Fehler.

Dieses Verhalten tritt normalerweise in einem sehr einfachen Fall auf: Sie verwenden eine Art von Funktionen zur automatischen Vervollständigung. Der Browser startet eine Verbindung für Abfragetoken und stoppt und startet dann eine weitere Anforderung für weitere Token. Sie werden mit vielen Broken Pipes enden. Und das war bis zum letzten Release kein Problem , was den Dev-Server komplett blockiert.
Der Vorschlag, einen Anwendungsserver mit vollem Funktionsumfang zu verwenden, ist eine gute Problemumgehung, aber ich sehe hier immer noch ein Problem. Natürlich ein reines Entwicklungsproblem, aber die Tatsache, dass es so häufig ausgelöst wird, macht es für viele Entwickler störend, die nicht an _Protokollinterna_ gewöhnt sind.
Eine gebrochene Pipe ist sehr häufig (denken Sie an eine lange Anforderung aus Versehen und der Entwickler, der auf die Schaltfläche zum Stoppen des Browsers drückt) und sollte den Entwicklungsserver nicht beschädigen.
Nur meine Meinung. :)

@xcash

Dieses Verhalten tritt normalerweise in einem sehr einfachen Fall auf: Sie verwenden eine Art von Funktionen zur automatischen Vervollständigung. Der Browser startet eine Verbindung für Abfragetoken und stoppt und startet dann eine weitere Anforderung für weitere Token.

Wenn es damit zusammenhängt, kann ich bestätigen, dass dieses Problem mit browsersync mit gulp.js .

Hat jemand eine Lösung, die den Betrieb eines WSGI-Servers nicht beinhaltet? Ich scheine auf dieses Problem zu stoßen, wenn Bots einen SYN-Scan gegen meinen Host durchführen.

@glennzw können Sie Ihre Umgebung genauer beschreiben? Sie sollten Ihren Entwicklungsserver nicht im offenen Web öffentlich zugänglich machen, auf den Bots zugreifen können. :) In einer solchen Situation, wie einem Demo-Host für Clients, ist es immer besser, zumindest einen echten Anwendungsserver wie gunicorn zu verwenden, der einen wirklich kleinen Footprint hat.

FWIW, ich habe nicht viel mit Veröffentlichungen Schritt gehalten und dieses (sehr nervige) Problem trat bei mir irgendwann zwischen Mai - August 2016 auf, soweit ich das beurteilen kann. Ich habe dies zu meinem setup.py install_requires = ['Werkzeug<0.11', 'flask<0.11', ... hinzugefügt - was das Problem zu umgehen scheint (IME, nur das Anheften von Werkzeug schien nicht zu funktionieren?)

Für mich war der Duplizierungsfall einfach genug - eine Seite laden, aber nicht zu Ende laden lassen. Das heißt, lösen Sie einfach einen _any_ Broken Pipe-Fehler aus - und der Webserver stürzt ab und kann alle anderen Anfragen nicht bedienen. IMHO, Webserver können nicht _umfallen_, wenn ein Client die Verbindung vorzeitig beendet - auch nicht Entwicklungsserver.

Könnte es sein, dass Sie alle irgendwo passthrough_errors eingestellt haben?

@untitaker in diesem Fall Paletten/Kolben#1674 Paletten/Kolben#1679 Paletten/Kolben#1928 möglicherweise verwandt?

Ich weiß nicht, ich möchte, dass einer der Reporter dies bestätigt.

Am 26. August 2016 17:05:25 MESZ schrieb David Lord [email protected] :

@untitaker in diesem Fall Paletten/Kolben#1674 Paletten/Kolben#1679
Paletten/Kolben#1928 möglicherweise verwandt?

Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an:
https://github.com/pallets/werkzeug/issues/954#issuecomment -242761250

Gesendet von meinem Android-Gerät mit K-9 Mail. Bitte entschuldigen Sie meine Kürze.

cc @miguelgrinberg

Ich denke, Werkzeug sollte mit Fehlern beim Zurücksetzen von Rohren und Verbindungen umgehen. Diese sind wirklich kein Hinweis auf einen Fehler, der Client ist einfach weggegangen. Es scheint, dass in diesem Fall eine spezielle Ausnahme ausgelöst werden sollte, die vom oben genannten Catch-All als eine zu ignorierende Ausnahme erkannt wird, selbst wenn Error Passthrough gesetzt ist.

So macht es Gunicorn: https://github.com/benoitc/gunicorn/blob/39f62ac66beaf83ceccefbfabd5e3af7735d2aff/gunicorn/workers/sync.py#L151 -L154

Das soll es tun. Ich versuche herauszufinden, wie man reproduziert
dieses Verhalten, aber es ist noch kein eindeutiger Testfall verfügbar. Daher die Frage
ungefähr passthrough_errors .

Ich vermute, dass dies kein Fehler in Werkzeug ist und dass der Browser des Benutzers
hat einfach noch eine Verbindung offen, die andere Anfragen blockiert (anstelle der
Serverabsturz). Wenn Sie Ihren Browser schließen und erneut öffnen, sollte der Server
Funktion wieder.

Am Freitag, den 26. August 2016 um 11:54:16 -0700 schrieb Miguel Grinberg:

Ich denke, Werkzeug sollte mit Fehlern beim Zurücksetzen von Rohren und Verbindungen umgehen. Diese sind wirklich kein Hinweis auf einen Fehler, der Client ist einfach weggegangen. Es scheint, dass in diesem Fall eine spezielle Ausnahme ausgelöst werden sollte, die vom oben genannten Catch-All als eine zu ignorierende Ausnahme erkannt wird, selbst wenn Error Passthrough gesetzt ist.

So macht es Gunicorn: https://github.com/benoitc/gunicorn/blob/39f62ac66beaf83ceccefbfabd5e3af7735d2aff/gunicorn/workers/sync.py#L151 -L154

Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an:
https://github.com/pallets/werkzeug/issues/954#issuecomment -242821084

Ach ja, und gebrochene Pipe-Fehler _werden_ angezeigt, ja, aber sie sollten den Server niemals wie beschrieben auflegen. Siehe vorherigen Kommentar zum möglichen Grund.

Ich habe die neuesten Bits erneut getestet und sehe immer noch das gleiche Verhalten in meiner Umgebung. Aber da Sie anscheinend Schwierigkeiten haben, sich zu reproduzieren, habe ich versucht, herauszubekommen, warum ich etwas Besonderes bin.

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

Es funktioniert wie erwartet mit flask run aber der Webserver würde abstürzen, wenn Sie Ihren Webbrowser schließen, bevor die Antwort beim Start über python hello.py

Es scheint, dass ein Teil Ihrer Antwort verloren gegangen ist.

Am Freitag, den 26. August 2016 um 12:29:39 -0700 schrieb Clayg:

Ich habe die neuesten Bits erneut getestet und sehe immer noch das gleiche Verhalten in meiner Umgebung. Aber da Sie anscheinend Schwierigkeiten haben, sich zu reproduzieren, habe ich versucht, herauszubekommen, warum ich etwas Besonderes bin.

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

Ja, in lockeren Triple-Ticks blockiert man Zitate und ctrl-return ist wie man eine neue Zeile setzt
Auf github blockierst du mit Triple-Ticks ein Angebot, aber ctrl-return ist, wie du es einreichst
... sowieso ... Muskelgedächtnis

Ich habe meinen Beitrag sofort nach dem Absenden bearbeitet, um ihn abzuschließen - und ich antworte nur, weil es so aussieht, als würden Sie per E-Mail antworten und ich bin mir nicht sicher, ob github Ihnen nach meiner Bearbeitung eine weitere Benachrichtigung senden wird.

Ich kann mit dem Schlaftest von

Ich habe den gleichen Trick auch mit meinem Flask-Video-Streaming-Beispiel ausprobiert, das eine Streaming-Antwort verwendet, um Videoframes in einem nie endenden Stream bereitzustellen, und selbst für diesen kann ich den Browser schließen und die Anfrage endet ohne Fehler. Dies ist seltsam, da ich mir sicher bin, dass diese Anwendung in der Vergangenheit einen gebrochenen Pipe-Fehler an die Konsole auslöste, bevor die Anforderung beendet wurde.

Eigentlich habe ich zu früh gesprochen. Ich kann jedes Mal mit meiner Video-Streaming-App reproduzieren, wenn ich Python 2.7 verwende. Ich kann am 3.5 nicht reproduzieren. Alle oben genannten Stack-Traces sind für 2.7. Denken Sie also daran, wenn Sie mit Python 3 testen.

Noch ein interessanter Datenpunkt. Bei der Ausführung mit dem Reloader startet der Master-Prozess, der den Reloader ausführt, beim Beenden des untergeordneten Prozesses einen anderen, sodass keine Unterbrechung auftritt. Wenn Sie den Server jedoch ohne den Reloader betreiben, bringt Sie der Broken-Pipe-Fehler zurück zur Konsole.

Bearbeiten: Ignorieren Sie den Reloader, der einen anderen Prozessteil startet, der nicht zu passieren scheint, und stattdessen habe ich wahrscheinlich die Auswirkungen der Änderung der Passthrough-Fehlereinstellung gesehen.

Okay, hier ist die Analyse dessen, was meiner Meinung nach passiert:

  • Der Kunde verschwindet mitten in der Anfrage
  • Die Anfrage geht weiter. Die Socket-Verbindung scheint gepuffert zu sein, sodass Schreibvorgänge auf den Socket in den meisten Fällen keine Probleme verursachen.
  • Sobald die Anfrage beendet ist, gibt die Socket-Serverklasse flush() auf dem Socket aus. Dies war Gegenstand eines alten Fehlers in der Python-Bibliothek, der derzeit behoben wird: http://bugs.python.org/issue14574. Die Lösung in diesem Fix bestand darin, socket.error abzufangen und zu ignorieren.
  • Dann versucht der Socket-Server, die Verbindung zu schließen. Dies ist der folgende Stack-Frame aus dem Backtrace vom OP:

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

  • Leider ist in Python 2.7 das erste, was die Methode socket.close() tut, wieder ein Flush:

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

  • Dieser zweite Versuch eines Flushs ist nicht durch ein try/except geschützt, daher wird die EPIPE-Ausnahme ausgelöst.
  • Der Socket-Server fängt die Ausnahme ab und liefert sie dann an die Methode handle_error() des Servers.
  • Die Werkzeug-Implementierung von handle_error() betrachtet die Einstellung passthrough_errors , und da wir diese immer auf True , wird der EPIPE-Fehler erneut ausgelöst und lässt ihn bis zum oben.

Der Socket-Code von Python 3 ist völlig anders, und insbesondere scheint er keine Flush-Aufrufe ohne try/Exceptions um sie herum zu haben. Der EPIPE-Fehler sprudelt bei Verwendung von Python 3 nicht einmal an Werkzeug heran.

Haben wir passthrough_errors überhaupt auf true gesetzt? In Werkzeug ist es standardmäßig falsch.

Am 27. August 2016 02:10:13 MESZ schrieb Miguel Grinberg [email protected] :

Okay, hier ist die Analyse dessen, was meiner Meinung nach passiert:

  • Der Kunde verschwindet mitten in der Anfrage
  • Die Anfrage geht weiter. Die Steckdosenverbindung scheint
    gepuffert, sodass Schreibvorgänge auf den Socket in den meisten Fällen keine verursachen
    Probleme.
  • Sobald die Anfrage endet, gibt die Socket-Serverklasse ein flush()
    an der Steckdose. Dies war Gegenstand eines alten Fehlers in der Python-Bibliothek
    das ist derzeit behoben: http://bugs.python.org/issue14574. Die
    Die Lösung in diesem Fix bestand darin, socket.error abzufangen und zu ignorieren.
  • Dann versucht der Socket-Server, die Verbindung zu schließen. Dies ist das
    folgenden Stack-Frame, aus dem Backtrace vom OP:
 File "/usr/lib/python2.7/SocketServer.py", line 710, in finish
 self.wfile.close()

  • Leider ist in Python 2.7 das erste, was socket.close()
    Methode wird wieder gespült:
 File "/usr/lib/python2.7/socket.py", line 279, in close
 self.flush()

  • Dieser zweite Versuch eines Flushs ist nicht durch ein try/except geschützt, also
    es löst die EPIPE-Ausnahme aus.
  • Der Socket-Server fängt die Ausnahme ab und liefert sie dann an den
    handle_error() Methode des Servers.
  • Die Werkzeug-Implementierung von handle_error() betrachtet die
    passthrough_errors Einstellung, und da wir dies immer auf . eingestellt haben
    True , erhöht den EPIPE-Fehler erneut und lässt ihn nach oben sprudeln.

Der Socket-Code von Python 3 ist völlig anders, und insbesondere
es scheint keine Flush-Aufrufe ohne Try/Exceptions zu geben
Sie. Der EPIPE-Fehler sprudelt bei der Verwendung nicht einmal an Werkzeug heran
Python3.

Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an:
https://github.com/pallets/werkzeug/issues/954#issuecomment -242881523

Gesendet von meinem Android-Gerät mit K-9 Mail. Bitte entschuldigen Sie meine Kürze.

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

Ich denke, passthrough_errors sollte von app.debug abhängig sein. NVM, ist nutzlos

Ich sehe keine andere Möglichkeit, als diese PR tatsächlich rückgängig zu machen. passthrough_errors=True tut einfach, was es tun soll, was kein gutes Standardverhalten ist, wenn man keinen Debugger an das Programm angehängt hat.

Egal, ich habe einen anderen Weg gefunden. Zwei PRs:

Da es sich bei beiden um Verhaltensänderungen im weitesten Sinne handelt, möchte ich sie lieber nicht zurückportieren.

Ich denke, https://github.com/pallets/flask/pull/1996 ist eine akzeptable Lösung. Wichtig ist, dass es den häufigen Fall behebt, in dem Ausnahmen nicht weitergegeben werden sollen. Wenn Sie sich ausbreiten möchten, dann debuggen Sie, und in diesem Fall ist es keine große Sache, den socket.error weiterzugeben, wenn er nicht verbreitet werden sollte.

Der Fix https://github.com/pallets/werkzeug/pull/998 ist jedoch nicht großartig. Die Anwendung könnte diese Ausnahmen legitimerweise von etwas auslösen, das sie mit Sockets in ihren eigenen Handlern macht, und diese würden ebenfalls stummgeschaltet. Die ideale Lösung wäre, dass diese an der Stelle, an der sie auftreten, abgefangen und dann als benutzerdefinierte Ausnahmeklasse erneut ausgelöst werden, die handle_error erkennen und ignorieren kann. Angesichts der Tatsache, dass wir SocketServer wahrscheinlich nicht ändern oder überladen wollen, denke ich, dass ich diesen Teil einfach so lassen möchte, wie er ist. Sie erhalten die EPIPE auf der Konsole gespeichert, aber nur unter Python 2, und zumindest wird sie den Server nicht stoppen, nachdem der andere Fix eingeht. Es ist harmlos und ein Verhalten, das in der Vergangenheit existierte, bevor ich das gemacht habe passthrough_errors ändern.

Das von Ihnen beschriebene Verhalten tritt jedoch nur auf, wenn PASSTHROUGH_ERRORS aktiviert ist. Andernfalls wird die Ausnahme innerhalb von Flask abgefangen.

Ich denke, diese kosmetische Verbesserung ist es jedoch nicht wert.

Am 27. August 2016, 18:29:30 Uhr MESZ schrieb Miguel Grinberg [email protected] :

Ich denke, https://github.com/pallets/flask/pull/1996 ist akzeptabel
Lösung. Das Wichtigste ist, dass es den allgemeinen Fall behebt, in dem
Sie möchten nicht, dass Ausnahmen propagiert werden. Wenn Sie sich vermehren möchten,
dann debuggen Sie und erhalten in diesem Fall den socket.error
verbreitet, wenn es nicht sollte, ist keine große Sache.

Der https://github.com/pallets/werkzeug/pull/998 Fix ist nicht so toll
obwohl. Die Anwendung kann diese Ausnahmen berechtigterweise von
etwas, das es mit Sockets in seinen eigenen Handlern macht, und diese würden
auch zum Schweigen gebracht werden. Die ideale Lösung wäre, dass diese gefangen werden
an der Stelle, an der sie auftreten, und dann als benutzerdefinierte Ausnahme erneut geraist
Klasse, die handle_error erkennen und ignorieren kann. Da wir
Wahrscheinlich möchte ich SocketServer nicht ändern oder überladen, ich denke, mein
Abstimmung ist, diesen Teil einfach so zu lassen, wie er ist. Sie erhalten die EPIPE gedumpt zu
die Konsole, aber nur auf Python 2, und zumindest wird es nicht aufhören
der Server nach dem anderen Fix geht. Es ist harmlos, und es ist ein
Verhalten, das in der Vergangenheit existierte, bevor ich die
passthrough_errors ändern.

Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an:
https://github.com/pallets/werkzeug/issues/954#issuecomment -242926832

Gesendet von meinem Android-Gerät mit K-9 Mail. Bitte entschuldigen Sie meine Kürze.

Im Master behoben.

Das von Ihnen beschriebene Verhalten tritt jedoch nur auf, wenn PASSTHROUGH_ERRORS aktiviert ist

Ja, dieses Detail habe ich weggelassen. Aber diese Änderung würde sogar Python 3 betreffen, wo nichts davon ein Problem ist. Auf Py3 mit aktivierten Passthrough-Fehlern würde ein legitimer socket.error, der von der Anwendung ausgelöst wurde, stummgeschaltet.

Meister scheint wfm, freue mich auf die nächste Veröffentlichung, danke!

Hallo, ich benutze einen Werkzeug-Entwicklungsserver, der hinter NGINX läuft, ich stehe vor dem gleichen Problem, könnte mir jemand dabei helfen,
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

Bitte helft

Ragav verwendet einen anderen Anwendungsserver anstelle von werkzeugs eingebautem dev
Server, wie Gunicorn. Es ist derzeit die einzige Lösung.

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

Hallo, ich verwende einen Werkzeug-Entwicklungsserver, der hinter NGINX läuft, ich stehe vor dem
Das gleiche Problem könnte mir jemand dabei helfen, ```
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 | Fehler auf Anfrage:
11:13:11 web.1 | Traceback (letzter Anruf zuletzt):
11:13:11 web.1 | Datei "/home/ommi/frappe-bench/env/
lib/python2.7/site-packages/werkzeug/serving.py", Zeile 193, in run_wsgi
11:13:11 web.1 | ausführen (self.server.app)
11:13:11 web.1 | Datei "/home/ommi/frappe-bench/env/
lib/python2.7/site-packages/werkzeug/serving.py", Zeile 184, in execute
11:13:11 web.1 | schreiben (Daten)
11:13:11 web.1 | Datei "/home/ommi/frappe-bench/env/
lib/python2.7/site-packages/werkzeug/serving.py", Zeile 152, in write
11:13:11 web.1 | self.send_header(Schlüssel, Wert)
11:13:11 web.1 | Datei "/usr/lib/python2.7/BaseHTTPServer.py", Zeile 401,
in send_header
11:13:11 web.1 | self.wfile.write("%s: %s\r\n" % (Schlüsselwort, Wert))
11:13:11 web.1 | IOFehler: [Errno 32] Rohrbruch

Bitte helft


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/pallets/werkzeug/issues/954#issuecomment -247243400,
oder den Thread stumm schalten
https://github.com/notifications/unsubscribe-auth/AA6MZ6DNiRIfL91CLeYOoA70W9_nQQzGks5qqOCMgaJpZM4I58cy
.

Geleitet vom letzten Fix-Commit konnte ich dieses Problem beheben, indem ich app.run mit passthrough_errors=False aufrief. YMMV

Der Fehler, der den Absturz verursachte, wurde in Version 0.12 behoben , die am 21. Dezember 2016 veröffentlicht wurde.

  • Machen Sie eine Verhaltensänderung rückgängig, die den Entwicklungsserver zum Absturz brachte, anstatt einen internen Serverfehler zurückzugeben (Pull-Request #2006).

Version 0.12 wurde erst letzte Woche veröffentlicht.

Am Mo, 20. März 2017 um 09:05:00 -0700 schrieb Alan Rotman:

Der Fehler, der den Absturz verursachte, wurde in Version 0.12 behoben , die am 21. Dezember 2016 veröffentlicht wurde.

  • Machen Sie eine Verhaltensänderung rückgängig, die den Entwicklungsserver zum Absturz brachte, anstatt einen internen Serverfehler zurückzugeben (Pull-Request #2006).

--
Sie erhalten dies, weil Sie den Status Öffnen/Schließen geändert haben.
Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an:
https://github.com/pallets/werkzeug/issues/954#issuecomment -287807602

Ich habe heute ReleaseNotes gesehen und lange auf diesen Fix gewartet.

Siehe: http://flask.pocoo.org/docs/0.12/changelog/
Version 0.12
Erschienen am 21. Dezember 2016, Codename Punsch.

https://pypi.python.org/pypi/Flask/0.12
Dateityp Py Version hochgeladen nach Größe
Flask-0.12-py2.py3-none-any.whl (md5) Python Wheel 2.7 2016-12-21 80KB
Flask-0.12.tar.gz (md5) Quelle 2016-12-21 519KB

Ah, ja, du meinst Flask. Sicher.

Am Mo, 20. März 2017 um 09:22:15 -0700 schrieb Alan Rotman:

Ich habe heute ReleaseNotes gesehen und lange auf diesen Fix gewartet.

Siehe: http://flask.pocoo.org/docs/0.12/changelog/
Version 0.12
Erschienen am 21. Dezember 2016, Codename Punsch.

https://pypi.python.org/pypi/Flask/0.12
Dateityp Py Version hochgeladen nach Größe
Flask-0.12-py2.py3-none-any.whl (md5) Python Wheel 2.7 2016-12-21 80KB
Flask-0.12.tar.gz (md5) Quelle 2016-12-21 519KB

--
Sie erhalten dies, weil Sie den Status Öffnen/Schließen geändert haben.
Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an:
https://github.com/pallets/werkzeug/issues/954#issuecomment -287813405

Nur eine Anmerkung für alle, die auf dieses Problem stoßen, wenn sie Flask 0.12.2 auf werkzeug im threaded=True-Modus ausführen:
Im Thread-Modus scheint es standardmäßig immer noch so zu sein, dass jeder Werkzeug-Thread dieses Problem tatsächlich hat, dh wenn Sie eine Route anfordern, deren Rückkehr einige Zeit dauert, und dann die Verbindung vom Client schließen, protokolliert dieses bestimmte Werkzeug einen IOError Broken Pipe und dann stirbt. Der Server funktioniert insgesamt weiterhin, außer dass ich in meiner Anwendung feststellte, dass dies irgendwie ein Speicherleck verursachte, wobei der Kolbenprozess nach einem gebrochenen Rohr in einem beliebigen Thread langsam anwuchs, den gesamten RAM aufbrauchte und dann SWAP und dann endlich war vom Betriebssystem getötet.
Das explizite Senden von passthrough_errors=False in app.run scheint das Problem behoben zu haben - die Threads sterben nicht mehr, wenn der Client die Verbindung trennt, sie protokollieren den IOError und dann auch dies (was ich nie gesehen habe, ohne explizit passthrough_errors=False zu setzen):

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

Und dann läuft der Server wie gewohnt weiter. Ich muss noch ein paar Stunden warten, um zu sehen, ob das Speicherleck wieder auftaucht, aber ich hoffe, dass es nicht passiert.

Nur falls das für jemanden hilfreich ist.

Ich habe diesen Fehler auch in einem Ubuntu Docker-Container auf Kubernetes auf einer Ubuntu-VM gesehen:

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

Ich habe eine brandneue Ubuntu-Xenial-VM erstellt und denselben Code im Ubuntu-Docker-Container auf Kubernetes ausgeführt, und dieser Fehler wurde nicht angezeigt und Python Flask funktionierte wie erwartet. Ich denke, es war ein Problem mit meinem Host (Ubuntu VM).

@vhosakot Können Sie mir

In einer Routenfunktion habe ich eine andere Funktion verwendet, die für das Routing gedacht war.
Ich habe die Daten aus der Antwort dieser Funktion abgerufen.
Wenn ich jetzt _loads () _ für diese Daten verwendet habe, erhalte ich den Fehler.

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

Fehler: IOError: [Errno 32] Broken pipe

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

masklinn picture masklinn  ·  11Kommentare

davidism picture davidism  ·  9Kommentare

golf-player picture golf-player  ·  10Kommentare

mhelmetag picture mhelmetag  ·  8Kommentare

Nessphoro picture Nessphoro  ·  6Kommentare