Wie zu erkennen, wenn eine Aufgabe bereits in der Warteschlange im django-celery?

Hier ist mein setup:

  • django 1.3
  • Sellerie 2.2.6
  • django-celery 2.2.4
  • djkombu 0.9.2

In meinem settings.py Datei habe ich

BROKER_BACKEND = "djkombu.transport.DatabaseTransport"

d.h. ich bin nur mit der Datenbank in die Warteschlange Aufgaben.

Nun zu meinem problem: ich habe einen Benutzer initiiert die Aufgabe kann ein paar Minuten dauern, um abzuschließen. Ich möchte den task nur einmal ausführen pro Benutzer, und ich cache die Ergebnisse der Aufgabe in einer temporären Datei, so dass, wenn der Benutzer initiiert die task wieder, dass ich einfach nur wieder die Cache-Datei. Ich habe code, der so aussieht in meinem view-Funktion:

task_id = "long-task-%d" % user_id
result = tasks.some_long_task.AsyncResult(task_id)

if result.state == celery.states.PENDING:
    # The next line makes a duplicate task if the user rapidly refreshes the page
    tasks.some_long_task.apply_async(task_id=task_id)
    return HttpResponse("Task started...")
elif result.state == celery.states.STARTED:
    return HttpResponse("Task is still running, please wait...")
elif result.state == celery.states.SUCCESS:
    if cached_file_still_exists():
        return get_cached_file()
    else:
        result.forget()
        tasks.some_long_task.apply_async(task_id=task_id)
        return HttpResponse("Task started...")

Dieser code, der fast funktioniert. Aber ich laufen in ein problem, wenn der Benutzer schnell lädt die Seite. Es gibt ein 1-3 Sekunden Verzögerung zwischen, wenn Sie die Aufgabe in die Warteschlange eingereiht und, wenn Sie die Aufgabe schließlich zog Sie aus der Warteschlange entnommen und in einen Arbeiter. Während dieser Zeit, die Aufgabe, der Staat ist weiterhin ANHÄNGIG, die bewirkt, dass die view-Logik zur kick-off-eine doppelte Aufgabe.

Was ich brauchen, ist eine Möglichkeit zu sagen, wenn die Aufgabe bereits an die Warteschlange übermittelt wurde, so dass ich am Ende nicht Absenden zweimal. Gibt es einen standard-Weg, dies zu tun, in Sellerie?

  • Kann kick_off_the_long_task_again() stellen Sie sicher, dass die Aufgabe, verschoben Anhängig? Wenn dem so ist, kann eine ausreichende Verzögerung, um zu verhindern, dass die race-condition zwischen dem Benutzer und Sellerie.
  • kick_off_the_long_task_again() nicht im Ergebnis eine doppelte Aufgabe. Ich aktualisierte mein Beispiel um zu zeigen, wo der code wird stellen Sie eine doppelte Aufgabe.
  • Das war nicht meine Frage. Kann kick_off_the_long_task_again() überprüfen und warten, um sicher zu sein Sie die Aufgabe verschoben, bis vor dem Abschluss?
  • gut, sicher, aber das würde nicht scheinen, um etwas zu erreichen. Ergebnis.vergessen() löscht die Ergebnisse und stellt die Aufgabe zurück in der ANSTEHENDEN, so dass wir "wissen" der Staat bereits, abgesehen von einer anderen unwahrscheinlich race-Bedingung. Ich würde gerne zur Lösung meines ursprünglichen Problems zuerst, bevor man über die kleineren edge-Fällen.
  • Wenn die Pending-Zustand nicht gesehen werden können (weil Sie wartete, bis es übergeben wurde), dann ist dein problem ist gelöst, richtig? Oder ist es etwas anderes?
InformationsquelleAutor cwick | 2011-05-04
Schreibe einen Kommentar