CGI Script sauber beenden trotz Abbruch im Browser

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
momo
User
Beiträge: 9
Registriert: Donnerstag 19. März 2009, 17:52

Hallo liebes Forum,

ich habe ein CGI-Script in Python geschrieben, mit dem sich Benutzer in eine auf dem Server gespeicherte Liste (Textdatei) ein- oder austragen können. Jetzt habe ich festgestellt, dass wenn ein Benutzer im Browser auf "Abbruch" klickt, oder die Verbindung aus einem anderen Grund abbricht, mein Programm abgewürgt wird und die Textdatei mit den Daten u. U. im Eimer ist.

Eine mögliche Lösung wäre mit mehreren Kopien der Textdatei zu arbeiten und "überflüssige" dann beim nächsten Programmstart zu löschen.

Mit Google konnte ich für PHP ein Beispiel finden, dass noch gewisse Aufräumarbeiten beim Programmabbruch ermöglicht.

Gibt es so etwas auch für Python ?

Gruß,

momo
lunar

Ohne Code kann man da exakt gar nichts zu sagen, ins Blaue hineingeraten würde ich sagen, dass du die Datei ohne With-Anweisung oder umschließendes Try-Finally-Konstrukt geöffnet hast und daher der notwendige Aufruf der ".close()" Methode im Fehlerfall nicht stattfindet und dir daher raten, sich über Ausnahme-Behandlung in Python sowie über die With-Anweisung zu informieren. Desweiteren würde ich dir eindringlich raten, die Textdatei durch eine vernünftige Datenbank zu ersetzen, die mit nebenläufigem Zugriff und Transaktionen zurecht kommt, da dieses Problem dann gar nicht auftreten würde.

Zum Schluss natürlich noch der obligatorische Rat, doch bitte ein vernünftiges Web-Framework einzusetzen, gerade Python bietet da doch etwas für jeden Geschmack.
momo
User
Beiträge: 9
Registriert: Donnerstag 19. März 2009, 17:52

Hallo lunar !

Vielen Dank erstmal für deine Tipps.

Hier ein kurzes Beispielprogramm:

Code: Alles auswählen

#!/usr/local/bin/python
# -*- coding: utf-8 -*-


import cgi
import cgitb; cgitb.enable()
import time

print "Content-Type: text/html"     
print
print "Start"
try:
    Fhandle = open("test.txt","w") 
    for x in range(10):
        Fhandle.write('Vorgang %s\n'%x)
        Fhandle.flush()
        time.sleep(1) # lange Verarbeitung simulieren um Abbruch testen zu können
finally:
    Fhandle.write('close\n')
    Fhandle.close()
    
print "Verarbeitung erfolgreich beendet"
Wenn ich dich richtig verstanden habe, muss in der Datei test.txt in der letzten Zeile immer "close" stehen, egal, wann ich im Browser auf Stopp klicke. Leider tut es das nicht. Ich komme bis z. B. "Vorgang 5" und dann ist die Datei zu ende.

Wenn ich nun eine Datenbank einsetze habe ich ja das gleiche Problem, es sei denn ich kann alles in einer einzigen Transaktion erledigen, die dann eben noch "durchgeht" oder nicht. Klar, in meinem Fall ist das Problem dann gelöst. Ein Webframework wie z. B. Django hilft mir, soweit ich das verstanden habe, bei diesem Problem auch nicht, weil es als ja auch für die einzelnen Anfragen als CGI-Script läuft und nicht als vom Webserver unabhängiger Prozess.

Gruß,

momo
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

momo hat geschrieben: Wenn ich dich richtig verstanden habe, muss in der Datei test.txt in der letzten Zeile immer "close" stehen, egal, wann ich im Browser auf Stopp klicke. Leider tut es das nicht. Ich komme bis z. B. "Vorgang 5" und dann ist die Datei zu ende.
Nö. Du greifst ja noch einmal per write() auf die Datei zu. Evtl. führt das wiederum zu einem Fehler und dann muss da eben nichts in der Datei stehen!
momo
User
Beiträge: 9
Registriert: Donnerstag 19. März 2009, 17:52

Hallo Hyperion,

für den speziellen Fall, dass ich im Browser auf Stopp drücke doch schon, oder ? Die Datei "test.txt" kann ja noch beschrieben werden, nur die Standardausgabe eben nicht, oder ?

Das Programm wird leider recht radikal vom Webserver beendet, nicht mal mit dem atexit-Modul ist noch was zu machen. :cry:

Gruß,

momo
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Also dafür kenne ich mich im Bereich Webserver nicht genug aus. Kommt ja daruf an, wie der Server das handhabt.

Kommst Du denn nicht irgend wie an die Konfiguration des Servers heran? Da müßte man ja irgend etwas zu diesem Verhalten finden ...
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

momo hat geschrieben:Wenn ich dich richtig verstanden habe, muss in der Datei test.txt in der letzten Zeile immer "close" stehen, egal, wann ich im Browser auf Stopp klicke.
Da würde ich dir zustimmen. Passiert dies nicht, würde es bedeuten, dass der Webserver das Python Script sofort tötet, wenn der Browser die Verbindung dicht macht. Ich hätte vermutet, dass der Server das Script einfach in einen IO-Fehler laufen lässt, wenn es versucht, (mit print) in die geschlossenen Verbindung zu schreiben.

Du könntest schauen, ob du mittels des "signal"-Moduls ein SIGTERM, oder was der Webserver da auch immer schickt, abfangen kannst.

Stefan
Antworten