Ich habe einen Tornado-Server, der verwendet wird, um lang laufende (~ Minuten) Berechnungen zu übermitteln, indem er einigen Sellerie-Mitarbeitern Aufgaben mit einem RabbitMQ-Back-End übermittelt. Die Aufgaben, die eingereicht werden, werden in einem Tornado Koroutine in einem WebSocketHandler
ergibt:Tornado-Web-Sockets und lang laufende Sellerie-Aufgaben
class MainWSHandler(WebSocketHandler):
def open(self):
logging.info("Connection opened.")
def on_close(self):
logging.info("Connection closed.")
def on_message(self, message):
result = self.submit_task(message)
self.write_message("Calculation has been submitted")
@gen.coroutine
def submit_task(self, params):
result = yield gen.Task(long_calculation.apply_async, args=[params])
self.write_message("Completed calculation")
return result
Das funktioniert gut, wenn der Benutzer nie die Seite mit dem aktuell geöffneten Web-Buchse läßt. Wenn dies der Fall ist und der Web-Socket geschlossen wird, schlägt die zurückgegebene Nachricht self.write_message("Completed calculation")
mit einem WebSocketClosedError
fehl. Dies ist in den Fällen gut, in denen der Benutzer nicht beabsichtigt, eine Weile auf die Seite zurückzukommen (dh bis die Berechnung abgeschlossen ist).
Wenn jedoch der Benutzer eine Berechnung übergibt, die Seite verlässt und vor Abschluss der Berechnung zurückkehrt, wird derselbe Fehler ausgelöst, weil der Web-Socket geschlossen und ein neuer geöffnet wurde. Dies verhindert, dass sich die Berechnungsabschlussnachrichten an das Front-End ausbreiten.
Meine Frage ist: Ist es möglich, wieder an den gleichen Web-Socket zu verbinden? Oder wie kann ich alternativ sicherstellen, dass die zurückgegebene Nachricht nach Abschluss der Berechnung auf die aktuelle Seite des Benutzers gelangt?