Wir unterhalten derzeit einen selbst entwickelten Python- "Webserver", auf dem das Generieren der Antwort für einige Anfragen sehr lange dauern kann, hauptsächlich aufgrund umfangreicher Berechnungen. Bei diesen Anfragen handelt es sich im Grunde genommen um Posts mit sehr langen Zeitüberschreitungen (denken Sie an Minuten bis Dutzende von Minuten).
Ein Problem dieser Architektur besteht darin, dass manchmal eine solche Anforderung abgebrochen werden muss - z. B. hat der Benutzer beim Konfigurieren der Anforderung einen Fehler festgestellt. Derzeit ist die Stornierung eine weitere Anfrage, die die langfristige Anfrage storniert - aber es gibt viele Lücken, z. B. was passiert, wenn der Kunde die Website einfach schließt?
Gegenwärtig planen wir, die hausgemachte Abscheulichkeit eines Webservers einzustellen und auf etwas Sinnvolles umzusteigen - z. B. Flask, der mit wfastcgi in einem IIS ausgeführt wird. Aus politischen Gründen ist IIS so eingestellt, dass der Wechsel zu etwas wie Gunicorn aus dem Fenster ist.
Alle Entwicklungen sind ins Stocken geraten, weil niemand eine Idee hat, wie die von (w) fastcgi ausgeführten Prozesse beendet werden können - diese Sorge ist einfach nicht Teil der fastcgi-Spezifikation.
Mein Gefühl ist, dass ein Versuch, etwas zu erstellen, das dies beinhaltet, ein Fehler ist. Ich würde eine Lösung vorziehen, bei der der Server solche rechenintensiven Aufgaben einfach einem Hintergrundserver (Flasche + Sellerie?) Und den Front-End-Umfragen dafür entlädt.
Leider war die alte Lösung so lange vorhanden, dass einige Entwickler das Verhalten um jeden Preis beibehalten möchten.
Da ich kein Webserver-Typ bin, möchte ich einige Tipps / Muster, wie vernünftige Lösungen für ein solches Problem aussehen könnten.
quelle
Ich schlage vor, Sie schauen in wsgi und verwenden Multithreading . Sie können jede Anforderung in einem Thread verwalten und Zeitüberschreitungen im Thread implementieren. Sie sollten auch in der Lage sein, die Threads zu verwalten und Anforderungen einfacher abzubrechen.
quelle
Das Problem, mit dem Sie derzeit bei einem einfachen HTTP-Beitrag konfrontiert sind, kann in diesem Protokoll einfach nicht gelöst werden. HTTP arbeitet asynchron in strengen Clients / Servern, sodass keine serverseitige Benachrichtigung und kein nativer Abbruch erfolgt. Außerdem haben Sie das Problem, dass Antworten aufgrund von Zeitüberschreitungen im Internet verloren gehen. Ich werde einen anderen und modernen Ansatz vorschlagen. Haftungsausschluss: etwas weniger als 90% Browserunterstützung
Ich würde vorschlagen, dass Sie den Informationsfluss umkehren und Websockets verwenden. Was Sie tun müssen , wenn eine Aufgabe erledigt ist Ihr Benutzer zu benachrichtigen , und drücken Sie eine Benachrichtigung vom Server zum Client.
Wenn eine Aufgabe veröffentlicht wird oder genauer gesagt, als Ersatz für den Beitrag, öffnen Sie einen Websocket (verwenden Sie die von Ihnen gewünschte Servertechnologie, Tornado, Gevent, Python-Websocket usw.). Ordnen Sie den Task-Thread dem offenen Ereignis "Server-Websocket" zu. Wenn der Client beendet wird, sendet der Client ein Abschlussereignis an Ihren Websocket-Handler, damit Sie den damit verbundenen Thread beenden können. Wenn Ihre Aufgabe normal endet, kann der Server die Daten an den Client senden und den Websocket schließen. Außerdem muss der Server alle 30 Sekunden einen Ping-Befehl senden, da Websockets geschlossen werden, wenn sie länger als eine Minute inaktiv sind.
Wenn Sie dies anwenden, ist dies schneller und sauberer als eine clientseitige Abfrage, während Lückenprobleme gelöst werden, da Sie über einen echten bidirektionalen Kanal verfügen. Beachten Sie, dass Sie zusätzliche Dienste über das Aufgabenschema implementieren können, z. B. Sitzungen, Fortschritts-Pings usw.
quelle
Wenn Ihre Aufgabe so viel Zeit benötigt, tun Sie dies nicht auf diese Anfrage hin. Stellen Sie es in die Warteschlange und machen Sie einen anderen Prozess, der die Arbeit erledigt.
Nachdem die Arbeit erledigt ist, senden Sie einfach eine Benachrichtigung an den Benutzer, dass "Operation x" abgeschlossen ist. Zeigen Sie in der Zwischenzeit die Meldung "Ihre Arbeit wird in ca. x Minuten erledigt sein" an.
quelle