tomasz: PHP und lange dauernde DB-Statements

Hallo,

ich suche einen Weg mit php lange dauernde Datenbank-Statements zu starten und dem Benutzer zu antworten, auch wenn die Datenbank noch nicht fertig ist.

Also ich leite die Ausgabe der Datenbank irgendwo hin und
php wartet nur eine einstellbare Zeit, prueft ob Ergebnis vorliegt und Antwortet auch wenn Postgres bis dann noch nichts geliefert hat.

Ich wollte das mit "pcntl_fork" loesen, jedoch die "Process Control Functions" sind nur in CGI und CLI verfuegbar. Irgendwie muss aber ein fork erfolgen.

Fuer jeden Tipp dankbar
Tomasz

  1. Hello,

    ich suche einen Weg mit php lange dauernde Datenbank-Statements zu starten und dem Benutzer zu antworten, auch wenn die Datenbank noch nicht fertig ist.

    Also ich leite die Ausgabe der Datenbank irgendwo hin und
    php wartet nur eine einstellbare Zeit, prueft ob Ergebnis vorliegt und Antwortet auch wenn Postgres bis dann noch nichts geliefert hat.

    Ich wollte das mit "pcntl_fork" loesen, jedoch die "Process Control Functions" sind nur in CGI und CLI verfuegbar. Irgendwie muss aber ein fork erfolgen.

    Wenn Du die Prozesse dann noch sortiert bekommst...

    Was hältst Du denn von JavaScript auf dem Client und/oder von Frames.
    Du sendest einfach zwei Abfragen für eine Aufgabe. Die musst Du dann natürlich über die Session und über sleep()-->Schleife wieder in die richtige Reihenfolge bringen auf dem Server, da sie ja asynchron übertragen werden.

    Harzliche Grüße aus http://www.annerschbarrich.de

    Tom

    --
    Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
    Nur selber lernen macht schlau
  2. Moin tomasz

    ich suche einen Weg mit php lange dauernde Datenbank-Statements zu starten und dem Benutzer zu antworten, auch wenn die Datenbank noch nicht fertig ist.

    Kannst du das bitte präzisieren. Möchtest du dem Benutzer bereits Ergebnisse anzeigen bevor alle Ergebnisse vorliegen, oder eine Ausgabe in der Art "Abfrage läuft"?

    Grüsse
    Mike

    --
    Freunde kommen und gehen. Feinde sammeln sich an.
    1. Kannst du das bitte präzisieren. Möchtest du dem Benutzer bereits Ergebnisse anzeigen bevor alle Ergebnisse vorliegen, oder eine Ausgabe in der Art "Abfrage läuft"?

      "Abfrage läuft" soll ausgegeben werden.

      Was hältst Du denn von JavaScript auf dem Client und/oder von Frames.

      Moechte mich nicht auf Client-Funktionalitaet verlassen, also kein
      '<meta http-equiv="Refresh"' und kein JavaScript.

      tomasz

      1. Moin tomasz,

        "Abfrage läuft" soll ausgegeben werden.

        Dann ist flush() dein Freund.

        Grüsse
        Mike

        --
        Freunde kommen und gehen. Feinde sammeln sich an.
        1. Hello,

          "Abfrage läuft" soll ausgegeben werden.

          Dann ist flush() dein Freund.

          Aber nur, wenn Dein Webserver ein Apache ist, der auf Linux läuft. Sonst klappt das nicht.

          Harzliche Grüße aus http://www.annerschbarrich.de

          Tom

          --
          Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
          Nur selber lernen macht schlau
          1. Dann ist flush() dein Freund.

            Aber nur, wenn Dein Webserver ein Apache ist, der auf Linux läuft. Sonst klappt das nicht.

            Vielen Dank,

            probiere es Morgen aus.

            Guesse
            tomasz

          2. Moin Tom,

            Aber nur, wenn Dein Webserver ein Apache ist, der auf Linux läuft. Sonst klappt das nicht.

            Was verleitet dich zu dieser Ausage? Wir hatten das mal in einem anderen Thread geklärt. Es geht auch mit dem IIS. Man muss nur den Ausgabepuffer "faken" bzw. füllen.

            Grüsse
            Mike

            --
            Freunde kommen und gehen. Feinde sammeln sich an.
            1. Hello,

              Aber nur, wenn Dein Webserver ein Apache ist, der auf Linux läuft. Sonst klappt das nicht.

              Was verleitet dich zu dieser Ausage? Wir hatten das mal in einem anderen Thread geklärt. Es geht auch mit dem IIS. Man muss nur den Ausgabepuffer "faken" bzw. füllen.

              Ich habe da noch ein paarmal auf diversen Windows-Installationen getestet. Das mit dem Soft-Flush() des Buffers ist bei Windows sehr unterschiedlich und kann zwischen wenigen Bytes und einigen Kilobytes (der größte wollte 64kb) variieren. Es scheint auch von der momentanen Speicherauslastung abzuhängen.

              Also ist das keien Empfehlung wert, außer "Finger von"

              Harzliche Grüße aus http://www.annerschbarrich.de

              Tom

              --
              Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
              Nur selber lernen macht schlau
              1. Moin Tom,

                Ich habe da noch ein paarmal auf diversen Windows-Installationen getestet. Das mit dem Soft-Flush() des Buffers ist bei Windows sehr unterschiedlich und kann zwischen wenigen Bytes und einigen Kilobytes (der größte wollte 64kb) variieren. Es scheint auch von der momentanen Speicherauslastung abzuhängen.

                Also ist das keien Empfehlung wert, außer "Finger von"

                Ich kann nur sagen bei IIS 5 und NT 4.0 und XP und WIN 2000 läuft das excellent. Aber das mag jeder selbst versuchen.

                Grüsse
                Mike

                --
                Freunde kommen und gehen. Feinde sammeln sich an.
  3. Hallo wieder,

    flush() scheint doch nicht die gesuchte Loesung zu sein, denn

    nach dem DB-Statement hat php noch einiges zu tun bis alles komplett ist. Die Ausgabe wird im Ausgabe-Objekt gesammelt, erst zum Schluss wird alles gesendet. Mit Postgres wird manchmal auch mehrmals "gesprochen" im laufe eines Skripts. Es sollte also ggf. nach dem langen DB-Statement noch php ausgefuehrt werden, vielleicht auch noch ein weiteres DB-Statement.

    Ich moechte also eine funktion erstellen mit der ich immer eine zu lange dauernde DB-Kommunikation (z.B. eine laengere Transaktion) "abfangen" und weiterlaufen lassen kann, waerend der Benutzer eine Meldung bekommt und die Daten, die bis dahin fertig sind.

    Somit komme ich immer wieder auf fork.

    tomasz

    1. Hallo Tomasz,

      dein Ansatz, das Problem serverseitig zu lösen, mag richtig sein; ich denke sogar, ganz ohne serverseitige Unterstützung wird's nicht gehen. Aber ob flush() oder fork(), ein Problem bleibt doch immer noch:

      Wie bringst du des Users Browser dazu, einen Teil der Seite, den er schon empfangen hat, auch gleich anzuzeigen?
      Beispielsweise hat ein seeeehr verbreiteter Browser eines amerikanischen Softwarekonzerns die Angewohnheit, die Empfangsdaten erstmal päckchenweise zu sammeln, bevor er mal wieder ein Stück anzeigt. Besonders schön kann man das beobachten, wenn man lange Seiten über eine langsame Verbindung (Modem) abruft.
      Irgendwo geisterte mal die Behauptung rum, dass dieser Browser erst dann wieder ein Häppchen Information anzeigt, wenn sein interner Empfangspuffer von angeblich 4kB mal wieder voll ist (oder das Dokument fertig übertragen ist).
      Aus eigener Beobachtung würde ich sagen, das _könnte_ sogar stimmen.

      Und hier sehe ich das Hauptproblem, wenn du den allmählichen Fortschritt deiner DB-Abfrage anzeigen willst, um dem User zu zeigen, "ja, bin noch beschäftigt, hier hast du schon mal".

      Aber eine Lösung dieses Problems, wenn du denn eine findest, würde mich auch interessieren.

      Bye,

      Martin

      1. Und hier sehe ich das Hauptproblem, wenn du den allmählichen Fortschritt deiner DB-Abfrage anzeigen willst, um dem User zu zeigen, "ja, bin noch beschäftigt, hier hast du schon mal".

        Das habe ich nicht vor.
        Der Benutzer bekommt eine fertige (abgeschlossene) Seite die alles enthaellt, was im Ausgabe-Objekt war, aber noch nichts aus dem langen DB-Statement. Das kann er mit dem naechsten Klick abholen.

        tomasz