Timeout des Browsers während DB-Abfrage verhindern
Torsten Gart
- cgi
Hallo liebe Forumsmitglieder,
ich habe ein kleines Problem zu lösen:
Wir haben ein DB-System, daß rel. viele Daten auswerten soll, Das Problem ist, daß je nach Einstellung des gewünschten Zeitraumes, der betrachtet werden soll, soviele Berechnungen gemacht werden müssen, daß es zu einem Browser-Timeout kommen kann.
Nun ist es kein Problem, daß die Anzeige u.U. erst nach 15 Minuten kommt (kann man ja in der Zeit essen gehen :-}), aber dadurch, daß der Browser abbricht, ist die Anzeige gar nicht möglich, obwohl das Script weiterläuft.
Meine Frage ist, wie man dies am besten lösen kann.
Idee)
-Script startet und setzt in DB (oder Datei) einen Wert fertig=0
-DB-Abfrage läuft
-Es wird mittels refresh (5 Sekunden z.B.) immer wieder geguckt, ob fertig=1 ist. Wenn ja, dann wird ein von DB-Abfrage erzeugtes temporär-statisches File an den Browser geschickt. Ansonsten wird das Ganze wiederholt und an den Browser "bitte warten" ausgegeben.
Realisierung)
Ich frage mich, wie man das am Besten realisiert. Einfach wäre es, wie oben angedeutet, mittels temp. Dateien, die man erzeugt, später ausgibt.
Schöner fände ich es allerdings, wenn man mittels fork() (ich verwende Perl!) einen Childprozess erzeugt, der die DB-Abfrage erledigt, der Hauptprozess fragt einen Zustand ab.
Aber WIE würde das aussehen? D.h. wie sende ich z.B. bei Zustand "bitte warten" das Refresh an den Browser? Das ist ja das Problem, denn ich will ja das gesamte Script nicht nochmal starten.
Hat jemand sowas schonmal gemacht???
Danke schön!!!
Gruß Torsten
Hallo Thorsten,
Vorneweg: Mit Perl kenne ich mich kaum aus, daher weiß ich nicht, wieviel es
kann. Ich kenne jedoch C und viele UNIX-Features, die eigentlich auch unter
Perl vorhanden sein müssten.
Ich frage mich, wie man das am Besten realisiert. Einfach wäre es, wie
oben angedeutet, mittels temp. Dateien, die man erzeugt, später ausgibt.
Blöd. Du verlässt Dich darauf, dass der User nicht einfach mal Stopp drückt
und somit dein erstes Script abwürgt.
Schöner fände ich es allerdings, wenn man mittels fork() (ich verwende
Perl!) einen Childprozess erzeugt, der die DB-Abfrage erledigt, der
Hauptprozess fragt einen Zustand ab.
Das ist schon mal ein guter Ansatz. Jetzt brauchst Du nur noch das Stichwort
IPC. Message-Queues wären für Deinen Ansatz ideal. Folgender Ansatz:
Ablauf:
Dein Anzeigescript schaut nach, ob eine Message-Queue mit dem Ergebnis
schon vorhanden ist.
Ja => Auslesen der Message-Queue. Wenn nichts drinnen steht, dann bitte
warten. Wenn etwas drinnen steht, dann ist das als der Dateiname mit dem
Resultat zu werten. Message-Queue freigeben.
Nein => Kreierung des Kindprozesses und Ausgabe von Bitte Warten.
Kindprozess: Erzeugung der Message-Queue. Berechnung wird gestartet.
Ergebnis in einer temporären Datei zwischengespeichert. Wenn das Ergebnis
vorliegt, Dateiname in die Message-Queue schreiben und Przoess beenden.
Für message-Queses sind folgende Funktionen (unter C jetzt, wie gesagt, Perl
kenne ich nicht gut genug) relevant:
msgget
msgsnd
msgrcv
msgctl
Ach ja, vergiss nicht, das IPC_NOWAIT-Flag für msgrcv zu setzen, sonst hast
Du blokierende Aufrufe. (und die wollen wir ja nicht)
Hat jemand sowas schonmal gemacht???
Ich nicht. ;)
Weitere Frage: Kannst Du mit Optimierung nichts an Performance aus Deiner
DB-Abfrage rausholen?
Ich hoffe, der Ansatz hilft Dir.
Gruesse,
Christian