zwischenergebnisse während einer berechnung ausgeben

Django, Flask, Bottle, WSGI, CGI…
Antworten
klara-f
User
Beiträge: 19
Registriert: Dienstag 5. August 2014, 07:34

hallo forum,

ich suche nach einer möglichkeit, wie ich während einer berechnung zwischenergebnisse auf meiner homepage ausgeben kann, um den nutzer informiert zu halten. auch weil die berechnung in manchen fällen ziemlich lange dauert, wäre es hilfreich, ab und an mal eine rückmeldung an den user zu geben.
ich verwende django-cms.

etwas konkreter: in der berechnung habe ich eine schleife, die viele anfragen an google stellt und immer eine rückmeldung verarbeitet. sagen wir mal es sind 150 iterationen. jetzt würde ich gerne je iteration eine kurze meldung ausgeben lassen á la: 1/150, 2/150 ... 150/150 anfragen wurden getätigt. ich arbeite bisher nur mit return render_to_response() und damit ist nach meinem verständnis die methode danach beendet. heisst: ich käme nicht weiter als bis zur ausgabe 1/150, denn dann würde die methode abbrechen, obwohl ja noch ein bisschen was zu berechnen ist.

habt ihr da einen tipp/minimalbeispiel für mich?

viele grüße vom sonnigen sonntag
klara-f!
BlackJack

@klara-f: Das ist nicht so einfach weil HTTP im Grunde immer eine Anfrage/Verarbeitung/Antwort Reihenfolge beinhaltet. Eine Möglichkeit wäre es während der Verarbeitung den Fortschritt in eine Datenbank zu schreiben und diesen Wert vom Client separat regelmässig Abfragen zu lassen während die Verarbeitung läuft. Eine andere Möglichkeit wäre es die Verarbeitung nicht in einem Schritt zu machen sondern die 150 Iterationen über den Client zu machen.
klara-f
User
Beiträge: 19
Registriert: Dienstag 5. August 2014, 07:34

ok, soweit verstanden. aber wie sage ich denn meinem template, dass es während es auf ein ergebnis wartet, dass zwischendrin noch was ausgegeben wird? etwas in die datenbank zu schreiben, ist kein problem, aber, naja, wie halt mit dem template das lösen? müsste ich dann nicht wieder zwischendurch ein rendertoresponse in meine pythonprogrammteile eingeben?!
btw: die berechnung startet mit einem klick auf einen button. dann wird auf das ergebnis gewartet und dann wirds ausgegeben. genaugenommen startet der button den upload einer inputdatei und gleichzeitig startet dann die berechnung. ist also alles in einem form-befehl drin.
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@klara-f: Du kannst HTTPResponse einen Generator übergeben, so dass Django, ob und wie das der Browser aber verarbeitet ist unklar. Die saubere Methode ist es wirklich, in Python die Berechnung in einem Hintergrundthread laufen zu lassen und im Client regelmäßig den Status abzufragen.
BlackJack

@klara-f: Die Lösungen beinhalten alle beide JavaScript auf der Client-Seite und in beiden Fällen braucht man kein Template das HTML an den Browser ausliefert.
klara-f
User
Beiträge: 19
Registriert: Dienstag 5. August 2014, 07:34

ohje. jetzt habe ich mich ewig in django reingefriemelt und da kommt nun wieder was neues ... : (
was muss denn dann in dem java skriptteil drinstehen? wird die form in das javaskript eingebettet? oder ist der skriptteil nach dem absendebutton also nach der form?
der key für die datenbank und meinen datensatz wird mit jeder anfrage neu erzeugt. im einfachsten fall "beispieldatei1", "beispieldatei2" etc.
wenn mehrere user etwas hochladen, sprich den button drücken, wird immer ein neuer key erzeugt. ich weiß aber nie, welcher user jetzt welchen key hat, da diese zuordnung nicht existiert. deshalb wüsste ich auch nicht, welchem user ich welches zwischenergebnis ausgeben kann.
sorry, für das viele fragen... und danke schonmal für die hinweise @BlackJack!
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@klara-f: tja, so ist, wenn man sich reinpfriemelt: da kommt immer noch mehr ... :)

Ein mögliches Vorgehen ist das folgende: Nach dem Upload startet serverseitig ein neuer Prozeß, der die Google-Abfrage durchführt und Fortschritt und Daten in eine DB schreibt.
Der Response gibt eine Seite mit einem Javascript zurück, das wiederum Ajax-Requests an den Server sendet, die dann den Status abfragen und im Browser regelmäßig die Anzeige aktualisieren. Da der Response vom User-Upload kommt, ist auch dessen 'key' bekannt.
Mit Django selbst geht das prima, aber ich bin mir nicht sicher, ob Django-CMS und dessen Plug-In Struktur dafür geeignet sind.
BlackJack

Das JavaScript würde am Formular ansetzen. Mal angenommen man würde den zweiten Ansatz wählen, dann könnte man beim Druck auf die „Submit”-Schaltfläche die Formulardaten per JavaScript senden und beispielsweise JSON als Antwort erhalten welches ein Token/Schlüssel bekommt unter dem der Server die Formulardaten gespeichert hat und wie viele Schritte es gibt, also zum Beispiel 150. Und dann kann man per JavaScript der Reihe nach diese Schritte mit Anfragen anstossen. Und immer wenn ein Schritt abgeschlossen ist, kann man die Seite entsprechend aktualisieren. Mit einem Text oder auch ”grafisch”, zum Beispiel mit einem Fortschrittsbalken.

Ob dieser Ansatz der bessere ist, oder überhaupt machbar, oder das abarbeiten in einer lang laufenden Abfrage und das regelmässige abfragen des Fortschritts per JavaScript, hängt sehr stark davon ab was überhaupt gemacht werden soll. Ob die Schritte alle gleich, oder ähnlich sind, so dass man sie leicht einzeln ”aufrufbar” machen kann. Und welche Daten(mengen) bei jedem Schritt anfallen die zum nächsten weitergegeben werden müssen, und so weiter.
klara-f
User
Beiträge: 19
Registriert: Dienstag 5. August 2014, 07:34

so, vielen dank euch beiden für die antworten. es zeigt mir, dass mein problem lösbar ist. heisst aber auch noch etwas einlesen in verschiedene dinge. zu javascript kommt nun auch noch ajax hinzu.
@BlackJack, ich versteht den Ansatz inhaltlich (auch dass man sich überlegen muss, welchen von beiden man nun nutzt). bevorzugen würde ich das abfragen an die datenbank und dann die seite regelmäßig zu aktualisieren. kennt ihr oder könnt ihr mir einen link zu einem minimalbeispiel oder ein minimalbeispiel zur verfügung stellen?
klara-f
User
Beiträge: 19
Registriert: Dienstag 5. August 2014, 07:34

hallo forum, vor ein paar tagen war ich hier mit der frage, wie ich asynchron eine verarbeitung vornehmen kann:
  • upload eines dokumentes mit button.
  • button startet gleichzeitig die berechnung und dann wird so lange gewartet bis ich die lösung habe und gebe die zurück.
problem:
die berechnung dauert manchmal so lange, dass es einen timeout gibt und ein "internal server error" zurückgegeben wird. ich verwende uberspace.

:arrow: beim ersten schlaumachen bin ich jetzt auf celery gestoßen, um tasks anzustoßen. die installation geht auch auf dem uberspace.

frage:
in einer doku habe ich gelesen, dass auch ein server RabbitMQ installiert werden muss. das geht nicht. brauche ich diesen server überhaupt oder hat jemand so was schon mal auf uberspace zum laufen gebracht? und wenn: wie...?

viele grüße
klara-f!
BlackJack

@klara-f: Der andere ”stable” Broker ist Redis, und das wird von Uberspace unterstützt.
Antworten