Frage

Ich schrieb einen Python-Skript einige Daten aus CSV-Dateien zu verarbeiten. Das Skript dauert zwischen 3 bis 30 Minuten in Anspruch nehmen, abhängig von der Größe der CSV.

Jetzt mag ich in einer Web-Schnittstelle dazu bringen, so dass ich die CSV-Dateien von jedem Ort hochladen kann. Ich schrieb eine grundlegende HTTP-POST-Upload-Seite und verwenden Python CGI-Modul - aber das Skript gerade mal aus nach einiger Zeit.

Das Skript gibt HTTP-Header zu Beginn und gibt Datenbits nach über jede Zeile der CSV-Iteration. Als Beispiel auslösen würde diese Druck-Anweisung alle 30 Sekunden oder so.

# at the very top, with the 'import's
print "Content-type: text/html\n\n Processing ... <br />"

# the really long loop.
for currentRecord in csvRecords:
    count = count + 1
    print "On line " + str(count) + " <br />"

ging ich davon aus dem Browser die Header erhalten würde, und warten, da sie auf Empfang kleine Stücke von Daten halten. Aber was scheint tatsächlich zu geschehen ist es keine Daten überhaupt nicht erhalten, und Error 504 mal, wenn eine CSV mit vielen Linien gegeben.

Vielleicht gibt es einige Caching irgendwo passiert? Aus den Protokollen,

[Wed Jan 20 16:59:09 2010] [error] [client ::1] Script timed out before returning headers: datacruncher.py, referer: http://localhost/index.htm
[Wed Jan 20 17:04:09 2010] [warn] [client ::1] Timeout waiting for output from CGI script /Library/WebServer/CGI-Executables/datacruncher.py, referer: http://localhost/index.htm

Was ist der beste Weg, dies zu lösen, oder ist es nicht solche Skripte in einem Browser ausgeführt werden angemessen?

Edit: Dies ist ein Skript für meinen eigenen Gebrauch - ich normalerweise die Absicht, es auf meinem Computer zu verwenden, aber ich dachte, eine web-basierte Schnittstelle nützlich sein könnte während der Reise, oder zum Beispiel von einem Telefon. Außerdem gibt es wirklich nichts zu Download -. Das Skript wird höchstwahrscheinlich ein E-Mail einen Bericht aus am Ende

War es hilfreich?

Lösung

Ich würde trennen die Arbeit wie folgt aus:

  1. Eine Web-App-URL, die die entsandte CSV-Datei zu akzeptieren. Der Web-App setzt den CSV-Inhalt in eine Offline-Warteschlange, zum Beispiel einer Datenbanktabelle. Die Antwort des Web-App sollte eine eindeutige ID für die Warteschlange Element sein (automatisch inkrementierte ID-Spalte verwenden, zum Beispiel). Der Kunde muss diese ID für 3 Teil speichern.

  2. Ein Stand-alone-Service App, dass Umfragen die Warteschlange für die Arbeit, und die Verarbeitung der Fall ist. Nach Abschluss der Verarbeitung, speichern Sie die Ergebnisse in einer anderen Datenbanktabelle, die eindeutige ID als Schlüssel verwendet wird.

  3. Eine Web-App-URL, die verarbeiteten Ergebnisse erhalten können, http://server/getresults/uniqueid/. Wenn die Verarbeitung abgeschlossen ist (das heißt die eindeutige ID wird in der Ergebnisdatenbanktabelle gefunden), dann die Ergebnisse zurück. Wenn nicht beendet ist, sollte die Antwort ein Code sein, der dies angibt. Zum Beispiel eine benutzerdefinierte HTTP-Header, ein HTTP-Statusantwort, Antworttext 'PENDING' oder ähnlich.

Andere Tipps

Ich habe diese Situation hatte vor und ich Cronjobs. Der HTTP-Skript würde nur einen Job in einer Warteschlange schreiben ausgeführt (in einem Verzeichnis ein DB oder eine Datei) und die cronjob würde es lesen und diesen Job auszuführen.

Sie werden wahrscheinlich brauchen eine stdout.flush() zu tun, da das Skript nicht wirklich irgendetwas noch auf den Webserver zu schreiben, bis Sie einen Seitenpuffer im Wert von Daten geschrieben haben -., Die vor dem Timeout nicht geschieht

Aber die richtige Art und Weise zu lösen, das ist, wie andere vorgeschlagen, die Verarbeitung in einem separaten Thread / Prozess zu tun, und zeigt den Benutzer eine Auto-frischt Seite, die zeigt den Status, mit einem Fortschrittsbalken oder einem anderen ausgefallenen visuellen um zu verhindern, sie zu langweilen.

Siehe Randal Schwartz ist lange Prozesse durch CGI zuschauen. Der Artikel basiert auf Perl, aber die Technik ist nicht abhängig von der Sprache.

Sehr ähnliche Frage hier . Ich schlage vor, das Laichen den langwierigen Prozesses und Rückkehr ein Ajax-basierten Fortschrittsbalken für den Benutzer aus. So können sie Benutzer hat den Luxus des Web-Interface, und Sie haben den Luxus ohne Timeouts.

imho der beste Weg wäre, eine unabhängige Skript der Beiträge Updates irgendwo laufen (Flat-Datei, Datenbank, etc ...). Ich weiß nicht, wie ein unabhängigen Prozess von Python gabeln, so dass ich keine Codebeispiele geben kann.

zeigen, um Fortschritte auf einer Website eine Ajax-Anforderung an einer Seite implementieren, die diesen Status-Updates und zum Beispiel liest zeigt ein schöner Fortschrittsbalken.

Fügen Sie so etwas wie setTimeout ( "refreshProgressBar [...]) oder Meta-Refresh für Auto-Refresh.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top