Die Berichterstellung ergab Ergebnisse einer lang andauernden Sellerie-Aufgabe

Problem

Ich habe eine lang laufende Aufgabe in logische Unteraufgaben unterteilt, damit ich die Ergebnisse jeder Unteraufgabe nach Abschluss der Aufgabe protokollieren kann. Ich versuche jedoch, die Ergebnisse einer Aufgabe zu melden, die effektiv nie abgeschlossen wird (stattdessen ergebe ich Werte, wie es geht), und habe Mühe, dies mit meiner vorhandenen Lösung zu tun.

Hintergrund

Ich erstelle ein Webinterface für einige Python-Programme, die ich geschrieben habe. Benutzer können Aufträge über Webformulare senden und anschließend den Fortschritt des Auftrags erneut überprüfen.

Angenommen, ich habe zwei Funktionen, auf die jeweils über separate Formulare zugegriffen wird:

med_func: Die Ausführung dauert ca. 1 Minute. Die Ergebnisse werden an weitergeleitetrender(), die zusätzliche Daten erzeugt.long_func: Gibt einen Generator zurück. Jederyield dauert in der Größenordnung von 30 Minuten und sollte dem Benutzer gemeldet werden. Es gibt so viele Ausbeuten, dass wir diesen Iterator als unendlich betrachten könnenwiderrufen).Code, aktuelle Implementierung

Mitmed_funcIch berichte Ergebnisse wie folgt:

Beim Absenden des Formulars speichere ich einAsyncResult zu einemDjango-Sitzung:

    task_result = med_func.apply_async([form], link=render.s())
    request.session["task_result"] = task_result

Die Django-Ansicht für die Ergebnisseite greift darauf zuAsyncResult. Nach Abschluss einer Aufgabe werden die Ergebnisse in einem Objekt gespeichert, das als Kontext an eine Django-Vorlage übergeben wird.

def results(request):
    """ Serve (possibly incomplete) results of a session's latest run. """
    session = request.session

    try:  # Load most recent task
        task_result = session["task_result"]
    except KeyError:  # Already cleared, or doesn't exist
        if "results" not in session:
            session["status"] = "No job submitted"
    else:  # Extract data from Asynchronous Tasks
        session["status"] = task_result.status
        if task_result.ready():
            session["results"] = task_result.get()
            render_task = task_result.children[0]

            # Decorate with rendering results
            session["render_status"] = render_task.status
            if render_task.ready():
                session["results"].render_output = render_task.get()
                del(request.session["task_result"])  # Don't need any more

    return render_to_response('results.html', request.session)

Diese Lösung funktioniert nur, wenn die Funktion tatsächlich funktioniertbeendet. Ich kann logische Teilaufgaben von nicht verkettenlong_func, weil es eine unbekannte Anzahl vonyields (jede Iteration vonlong_funcDie Schleife von erzeugt möglicherweise kein Ergebnis.

Frage

Gibt es eine sinnvolle Möglichkeit, auf die erhaltenen Objekte einer extrem lang laufenden Sellerie-Aufgabe zuzugreifen, damit sie angezeigt werden können, bevor der Generator erschöpft ist?

Antworten auf die Frage(6)

Ihre Antwort auf die Frage