Ich habe eine web2py-Anwendung, die im Grunde als Browser-Schnittstelle für ein Python-Skript dient. Dieses Skript kehrt normalerweise ziemlich schnell zurück, kann aber gelegentlich lange dauern. Ich möchte eine Möglichkeit für den Benutzer bereitstellen, die Ausführung des Skripts zu stoppen, wenn es zu lange dauert.Stoppt eine lang andauernde Aktion in web2py mit Multiprocessing
ich derzeit Aufruf der Funktion wie folgt aus:
def myView(): # this function is called from ajax
session.model = myFunc() # myFunc is from a module which i have complete control over
return dict(model=session.model)
myFunc
, wenn sie mit bestimmten Optionen genannt, verwendet Multiprozessing aber noch endet eine lange Zeit. Ich brauche einen Weg, um die Funktion zu beenden, oder zumindest die Kinder des Threads.
Das erste, was ich versuchte, war myFunc
in einem neuen Prozess laufen zu lassen, und mein eigenes einfaches Ereignissystem rollt sie zu töten:
# in the controller
def myView():
p_conn, c_conn = multiprocessing.Pipe()
events = multiprocessing.Manager().dict()
proc = multiprocessing.Process(target=_fit, args=(options, events c_conn))
proc.start()
sleep(0.01)
session.events = events
proc.join()
session.model = p_conn.recv()
return dict(model=session.model)
def _fit(options, events pipe):
pipe.send(fitting.logistic_fit(options=options, events=events))
pipe.close()
def stop():
try:
session.events['kill']()
except SystemExit:
pass # because it raises that error intentionally
return dict()
# in the module
def kill():
print multiprocessing.active_children()
for p in multiprocessing.active_children():
p.terminate()
raise SystemExit
def myFunc(options, events):
events['kill'] = kill
Ich lief in ein paar großen Probleme mit diesem.
- Die Sitzung in
stop()
war nicht immer das gleiche wie die Sitzung inmyView()
, sosession.events
Keine war. - Selbst wenn die Sitzung die gleiche war, tötete
kill()
nicht ordnungsgemäß die Kinder. - Die lang laufende Funktion würde den web2py-Thread hängen, so dass
stop()
nicht einmal verarbeitet wurde, bis die Funktion beendet wurde.
Ich hielt Aufruf nicht join()
und AJAX mit dem Ergebnis der Funktion zu einem späteren Zeitpunkt zu holen, aber ich war für die spätere Verwendung in session
das Prozessobjekt speichern nicht in der Lage. Das Rohr schien in der Lage zu sein, gebeizt zu werden, aber dann hatte ich das Problem, von einer anderen Ansicht nicht auf die gleiche Sitzung zugreifen zu können.
Wie kann ich diese Funktion implementieren?
Können Sie bitte auf Ihre Antwort erweitern? Einige spezifische Dinge, die es wert wären, beantwortet zu werden: Startet der Scheduler die Aufgabe sofort, von einem Skript? Wie bekomme ich das Ergebnis der Aufgabe? Wie kann man die Aufgabe erzwingen? So beantwortet es die Frage nicht vollständig. – Scimonster
Ich habe die Antwort aktualisiert, um Ihre letzte Frage zu beantworten. Ihre ersten beiden Fragen werden in der verknüpften Dokumentation behandelt. Da sie allgemeine Scheduler-Funktionalität beinhalten und nicht Teil Ihrer ursprünglichen Frage sind, werde ich die Antwort nicht aktualisieren, aber ich werde kurz erwähnen, dass neue Aufgaben standardmäßig sofort in die Warteschlange gestellt werden (und Sie können einen Mitarbeiter zwingen, die Warteschlange sofort zu überprüfen 'sofort = Wahr '), und die' scheduler.task_status() 'Methode wird verwendet, um Ergebnisse abzurufen. – Anthony