Eine bereits ausgeführte Aufgabe mit Sellerie abbrechen?

90

Ich habe das Dokument gelesen und gesucht, kann aber keine eindeutige Antwort finden:

Können Sie eine bereits ausgeführte Aufgabe abbrechen? (Wie in der Aufgabe begonnen, dauert es eine Weile, und die Hälfte der Aufgabe muss abgebrochen werden)

Ich fand dies aus dem Dokument bei Celery FAQ

>>> result = add.apply_async(args=[2, 2], countdown=120)
>>> result.revoke()

Ich bin mir jedoch nicht sicher, ob dadurch Aufgaben in der Warteschlange abgebrochen werden oder ob ein laufender Prozess auf einem Worker abgebrochen wird. Vielen Dank für jedes Licht, das Sie werfen können!

dcoffey3296
quelle

Antworten:

176

Widerruf bricht die Ausführung der Aufgabe ab. Wenn eine Aufgabe widerrufen wird, ignorieren die Mitarbeiter die Aufgabe und führen sie nicht aus. Wenn Sie keine dauerhaften Widerrufe verwenden, kann Ihre Aufgabe nach dem Neustart des Workers ausgeführt werden.

http://docs.celeryproject.org/en/latest/userguide/workers.html#worker-persistent-revokes

widerrufen hat eine Beendigungsoption, die standardmäßig False ist. Wenn Sie die ausführende Aufgabe beenden müssen, müssen Sie terminate auf True setzen .

>>> from celery.task.control import revoke
>>> revoke(task_id, terminate=True)

http://docs.celeryproject.org/en/latest/userguide/workers.html#revoke-revoking-tasks

mher
quelle
3
Dies ist genau die Erklärung, nach der ich gesucht habe, danke!
dcoffey3296
1
Funktioniert dies in einer verteilten Umgebung? Ich meine, wenn ich Mitarbeiter auf mehreren Computern habe, die Aufgaben ausführen. Verfolgt Sellerie, auf welcher Maschine die Aufgabe ausgeführt wird?
Ksrini
1
Es tut. Die Kommunikation mit den Arbeitnehmern erfolgt über den Makler.
Mher
4
result.revoke (terminate = True) sollte dasselbe tun wie revoke (task_id, terminate = True)
CamHart
9
Die Verwendung der Option "Beenden" ist laut den aktuellen Sellerie-Dokumenten "ein letzter Ausweg für Administratoren". Sie laufen Gefahr, eine andere Aufgabe zu beenden, die kürzlich für diesen Worker gestartet wurde.
Kouk
38

In Celery 3.1 wird die API zum Widerrufen von Aufgaben geändert.

Gemäß den FAQ zu Sellerie sollten Sie result.revoke verwenden:

>>> result = add.apply_async(args=[2, 2], countdown=120)
>>> result.revoke()

oder wenn Sie nur die Aufgaben-ID haben:

>>> from proj.celery import app
>>> app.control.revoke(task_id)
Rockallite
quelle
25

@ 0x00mh Antwort richtig ist, aber die letzte Sellerie docs sagen , dass die Verwendung von terminateOption „ist für Administratoren ein letzter Ausweg “ , weil Sie versehentlich eine andere Aufgabe beenden können , die in der Zwischenzeit begonnen Ausführung. Möglicherweise ist eine bessere Lösung die Kombination terminate=Truemit signal='SIGUSR1'(wodurch die SoftTimeLimitExceeded-Ausnahme in der Aufgabe ausgelöst wird).

Kouk
quelle
2
Diese Lösung hat bei mir sehr gut funktioniert. Wenn SoftTimeLimitExceededin meiner Aufgabe ausgelöst wird, wird meine benutzerdefinierte Bereinigungslogik (implementiert über try/ except/ finally) aufgerufen. Dies ist meiner Ansicht nach viel besser als das, was es AbortableTaskbietet ( docs.celeryproject.org/en/latest/reference/… ). Bei letzterem benötigen Sie ein Datenbankergebnis-Backend und müssen den Status einer laufenden Aufgabe manuell und wiederholt überprüfen, um festzustellen, ob sie abgebrochen wurde.
David Schneider
2
Wie ist das besser, soweit ich verstehe, wenn es eine andere Aufgabe gibt, die vom Prozess übernommen wird, wird sie sowieso gestoppt, nur eine andere Ausnahme wird ausgelöst.
Marxin
Wenn ich benutze, worker_prefetch_multiplier = 1da ich nur ein paar lange laufende Aufgaben habe, sollte das Beenden in Ordnung sein - da durch das Beenden keine anderen Aufgaben ausgeführt werden - habe ich das richtig verstanden? @ Spicyramen
Maffe
1

Siehe die folgenden Optionen für Aufgaben: time_limit , soft_time_limit (oder Sie können es für Worker festlegen). Wenn Sie nicht nur Zeit der Ausführung steuern möchten, dann sehen abläuft Argument apply_async Methode.

simplylizz
quelle