it-swarm.com.de

Finden Sie heraus, ob eine Sellerieaufgabe existiert

Kann man herausfinden, ob eine Aufgabe mit einer bestimmten Aufgaben-ID existiert? Wenn ich versuche, den Status zu erhalten, werde ich immer ausstehend sein.

>>> AsyncResult('...').status
'PENDING'

Ich möchte wissen, ob eine gegebene Task-ID eine echte Sellerie-Task-ID und keine zufällige Zeichenfolge ist. Ich möchte unterschiedliche Ergebnisse, je nachdem, ob es eine gültige Aufgabe für eine bestimmte ID gibt.

In der Vergangenheit gab es möglicherweise eine gültige Aufgabe mit derselben ID, die Ergebnisse wurden jedoch möglicherweise aus dem Backend gelöscht.

37
dominik

Sellerie schreibt keinen Status, wenn die Aufgabe gesendet wird. Dies ist zum Teil eine Optimierung (Siehe http://docs.celeryproject.org/de/latest/userguide/tasks.html#state ). .

Wenn Sie es wirklich brauchen, können Sie einfach Folgendes hinzufügen:

from celery import current_app
# `after_task_publish` is available in celery 3.1+
# for older versions use the deprecated `task_sent` signal
from celery.signals import after_task_publish

@after_task_publish.connect
def update_sent_state(sender=None, body=None, **kwargs):
    # the task may not exist if sent using `send_task` which
    # sends tasks by name, so fall back to the default result backend
    # if that is the case.
    task = current_app.tasks.get(sender)
    backend = task.backend if task else current_app.backend

    backend.store_result(body['id'], None, "SENT")

Dann können Sie den Status PENDING testen, um festzustellen, dass eine Aufgabe (scheinbar) Nicht gesendet wurde:

>>> result.state != "PENDING"
28
asksol

AsyncResult.state gibt bei unbekannten Task-IDs PENDING zurück.

STEHT AUS 

Task wartet auf Ausführung oder ist unbekannt. Jede Task-ID, die nicht Bekannt ist, wird als ausstehend bezeichnet.

http://docs.celeryproject.org/de/latest/userguide/tasks.html#pending

Sie können benutzerdefinierte Aufgaben-IDs angeben, wenn Sie unbekannte von vorhandenen IDs unterscheiden müssen:

>>> from tasks import add
>>> from celery.utils import uuid
>>> r = add.apply_async(args=[1, 2], task_id="celery-task-id-"+uuid())
>>> id = r.task_id
>>> id
'celery-task-id-b774c3f9-5280-4ebe-a770-14a6977090cd'
>>> if not "blubb".startswith("celery-task-id-"): print "Unknown task id"
... 
Unknown task id
>>> if not id.startswith("celery-task-id-"): print "Unknown task id"
... 
9
mher

Im Moment verwende ich folgendes Schema:

  1. Task-ID abrufen.
  2. Setzen Sie den Memcache-Schlüssel wie 'task_% s'% task.id-Nachricht 'Gestartet'. 
  3. Übergeben Sie die Task-ID an den Client.
  4. Jetzt kann ich vom Client aus den Taskstatus überwachen (von Tasknachrichten in Memcache setzen).
  5. Stellen Sie die Tasknachricht auf "Bereit". 
  6. Von Client on Task bereit - Starten Sie eine spezielle Task, die den Schlüssel aus dem Memcache löscht und die erforderlichen Reinigungsaktionen ausführt.
2
Nikolay Fominyh

Sie müssen .get() für das von Ihnen erstellte AsyncTask-Objekt aufrufen, um das Ergebnis tatsächlich aus dem Backend abzurufen.

Siehe Sellerie FAQ .


Zur weiteren Klärung meiner Antwort.

Jede Zeichenfolge ist technisch gesehen eine gültige ID. Es gibt keine Möglichkeit, die Task-ID zu überprüfen. Der einzige Weg, um herauszufinden, ob eine Aufgabe vorhanden ist, besteht darin, das Backend zu fragen, ob es davon weiß, und dazu müssen Sie .get() verwenden.

Dies führt zu dem Problem, dass .get() blockiert, wenn das Backend keine Informationen über die von Ihnen angegebene Task-ID hat. Dies ist beabsichtigt, damit Sie eine Task starten und dann auf deren Abschluss warten können.

Bei der ursprünglichen Frage gehe ich davon aus, dass das OP den Status einer zuvor abgeschlossenen Aufgabe erhalten möchte. Dazu können Sie ein sehr kleines Timeout passieren und Timeout-Fehler abfangen:

from celery.exceptions import TimeoutError
try:
    # fetch the result from the backend
    # your backend must be fast enough to return
    # results within 100ms (0.1 seconds)
    result = AsyncResult('blubb').get(timeout=0.1)
except TimeoutError:
    result = None

if result:
    print "Result exists; state=%s" % (result.state,)
else:
    print "Result does not exist"

Es versteht sich von selbst, dass dies nur funktioniert, wenn Ihr Backend Ergebnisse speichert. Andernfalls kann nicht festgestellt werden, ob eine Task-ID gültig ist oder nicht, da nichts von ihnen aufgezeichnet wird.


Noch mehr Klarheit.

Was Sie tun möchten, kann nicht mit dem AMQP-Backend durchgeführt werden, da Ergebnisse nicht gespeichert werden, sondern weitergeleitet werden .

Mein Vorschlag wäre, zu einem Datenbank-Backend zu wechseln, sodass die Ergebnisse in einer Datenbank abgelegt werden, die Sie außerhalb der vorhandenen Selleriemodule abfragen können. Wenn in der Ergebnisdatenbank keine Aufgaben vorhanden sind, können Sie davon ausgehen, dass die ID ungültig ist.

0
Evan Borgstrom