Mit Tornado, ich habe eine Get-Anfrage, die eine lange Zeit dauert, da es viele Anfragen an einen anderen Web-Service macht und die Daten verarbeitet, könnte Minuten dauern, vollständig zu vervollständigen. Ich möchte nicht, dass dies den gesamten Webserver daran hindert, auf andere Anfragen zu antworten, was er derzeit tut.Tornado blockierende asynchrone Anfragen
Wie ich es verstehe, ist Tornado single-threaded und führt jede Anfrage synchron aus, obwohl sie asynchron behandelt (immer noch verwirrt auf diesem Bit). Es gibt Teile des langen Prozesses, die Pausenpunkte sein können, damit der Server andere Anfragen bearbeiten kann (mögliche Lösung?). Ich betreibe es auf Heroku mit einem einzigen Worker, also bin ich mir nicht sicher, wie das zu einem neuen Thread oder Multiprocessing führt, mit dem ich keine Erfahrung mit Python habe.
Hier ist was ich versuche zu tun: der Client macht den Anruf, um den Prozess zu starten, dann durchläuft ich alle 5 Sekunden einen anderen Anruf, um den Status zu überprüfen und die Seite mit neuen Informationen zu aktualisieren (lange Abfrage würde funktionieren auch, aber laufen auf dasselbe Problem hinaus). Das Problem besteht darin, dass das Starten des langen Prozesses alle neuen get-Anfragen (oder neue lange polling-Sitzungen) bis zum Abschluss blockiert.
Gibt es einen einfachen Weg, um diesen langen Anruf zu starten und ihn nicht den gesamten Webserver blockieren zu lassen? Gibt es irgendetwas, was ich in den Code schreiben kann, um zu sagen ... "Pause, gehe mit ausstehenden Anfragen und dann weiter"?
Ich muss eine Get-Anforderung auf ProcessHandler initiieren. Ich muss dann weiterhin StatusHandler abfragen können, während ProcessHandler ausgeführt wird.
Beispiel:
class StatusHandler(tornado.web.RequestHandler):
@tornado.web.asynchronous
def get(self):
self.render("status.html")
class ProcessHandler(tornado.web.RequestHandler):
@tornado.web.asynchronous
def get(self):
self.updateStatus("0")
result1 = self.function1()
self.updateStatus("1")
result2 = self.function2(result1)
self.updateStatus("2")
result3 = self.function3(result2)
self.updateStatus("3")
self.finish()
Haben Sie das tornado.gen-Modul ausprobiert? http://www.tornadoweb.org/documentation/gen.html –
erinnerst du dich, es als asynchroner Aufruf zu kommentieren: füge hinzu: @asynchronous auf deinen GET Methoden –
andyboot ja, ich habe @asynchronous auf meinen GET Methoden – JeffG