Martin Stoldt: Browser-Refresh während Perl-Programm läuft

Hallo Ihr Spezialisten!

da ich noch nicht weiß, wo ich suchen soll, meine Bitte um Auskunft oder Quellangabe.

Es läuft bei mir ein Perl-Programm (Suchalgorithmus). Vor der Suche soll das Programm an den Browser ein paar Zeilen ausgeben (Header und Teile vom Body "Ich suche gerade", z.Bsp), damit der Benutzer weiß, dass was geht. Bislang wird aber erst alle saugegeben, wenn die Suche fertig ist und das Perlprogramm die Kontrolle wieder abgegeben hat (beendet ist).

Wie kann ich jetzt während der Suche ein paar Zeilen ausgeben, oder wie lautet der Befehl oder wo kann ich selbst weitersuchen? Also eine Art "refresh" wie in curses.h ?

Danke schon mal für jeden Beitrag!

  1. NAchtrag:

    Der Programmaufbau ist heute schon:

    1. Initialisierung
    2. Einbinden extrener Module und Funktionen
    3. Parsen und Eingabeparameter lesen
    4. Ausgabe Header und erste Zeilen
    5. Auswertung Parameter und Suche starten
    6. verschiedene Suchen mit Ausgabe Ergebnisse
    7. Ausgababe Ende
    8. Alles sauber schließen und ende

    UND ERST JETZT erscheint die Ausgabe im Browser tatsächlich, nicht vorher bei 4.!

  2. Halihallo Martin

    Es läuft bei mir ein Perl-Programm (Suchalgorithmus). Vor der Suche soll das Programm an den Browser ein paar Zeilen ausgeben (Header und Teile vom Body "Ich suche gerade", z.Bsp), damit der Benutzer weiß, dass was geht. Bislang wird aber erst alle saugegeben, wenn die Suche fertig ist und das Perlprogramm die Kontrolle wieder abgegeben hat (beendet ist).

    Du hast es hier mit verschiedensten Caching-Mechanismen zu tun. Zum einen ist die
    Standardausgabe (cout, bzw. STDOUT) gecached, dann cached der Webserver und übertragen
    soll das ganze auch noch werden (bzw. dann schlussendlich im Browser dargestellt).
    Nun, das Perl-Caching kannst du mit autoflush ($|=1;) ausschalten. Alle anderen
    Cachings evtl. mit entsprechender Konfigurierung oder senden von nicht-Nutzdaten, wie
    z. B. einige kb's an Leerzeichen (aber spätestens hier wird das ganze, naja, sehr
    unschön).

    Mein Tipp: Verbessere deinen Suchalgorithmus. (der Tipp ist ernst gemeint!)

    Viele Grüsse

    Philipp

    --
    RTFM! - Foren steigern das Aufkommen von Redundanz im Internet, danke für das lesen der Manuals.
    Selbstbedienung! - Das SelfForum ist ein Gratis-Restaurant mit Selbstbedienung, Menüangebot steht in den </faq/> und dem </archiv/>.
    1. Danke Philipp

      Mein Tipp: Verbessere deinen Suchalgorithmus. (der Tipp ist ernst gemeint!)

      Es ist nur in begrenzen Rahmen möglich, weil ich auf das ERgebnis fremder Seiten auf fremden Servern zugreife und wenn dort ein "Timeout" vorliegt, merkt der LWP es erst, wenn $Timeout überschritten ist und die Suchzeit will ich nicht zu kurz setzen (also 5 Sekunden). Ich lasse schon parallel (tatsächlich) bis zu 25 Sohnprozesse gleichzeitig suchen, aber es dauert manchmal trotzdem 10-12 Sekunden und solange können einige Benutzer scheinbar nicht warten...

      Trotzdem danke, ich werde mit Autoflush mal probieren. Wichtig ist nur, daß der BEnutzer merkt, es tut sich was und das er nicht den länger werdenden Balken unten im Browser für eine Fehlfunktion des Programms hält!

      1. Hi Martin St,

        Trotzdem danke, ich werde mit Autoflush mal probieren.

        vergiß es. Es nützt Dir überhaupt nichts, wenn Deine Daten einen Meter weiter ungepuffert aus Deinem Programm kommen und an der ersten Straßenecke, auf die Du keinen Einfluß mehr hast, dann doch gepuffert werden.

        Dein Problem ist nicht Perl, sondern HTTP.

        Wichtig ist nur, daß der Benutzer merkt, es tut sich was und das er nicht den länger werdenden Balken unten im Browser für eine Fehlfunktion des Programms hält!

        Und genau das geht mit HTTP nicht.

        Was Du willst, das ist eine stehende Verbindung - also verwende ein Kommunikationsprotokoll, welches diese ermöglicht (schreibe ein Java-Applet und programmiere Deine Kommunikation selbst oder was auch immer).

        Viele Grüße
              Michael

        --
        T'Pol: I apologize if I acted inappropriately.
        V'Lar: Not at all. In fact, your bluntness made me reconsider some of my positions. Much as it has now.
        (sh:| fo:} ch:] rl:( br:^ n4:( ie:% mo:) va:| de:/ zu:| fl:( ss:) ls:~ js:|)
         => http://www.peter.in-berlin.de/projekte/selfcode/?code=sh%3A|+fo%3A}+ch%3A]+rl%3A(+br%3A^+n4%3A(+ie%3A%25+mo%3A)+va%3A|+de%3A%2F+zu%3A|+fl%3A(+ss%3A)+ls%3A~+js%3A|
        Auch diese Signatur wird an korrekt konfigurierte Browser gzip-komprimiert übertragen.
        1. Hallo Michael,

          vergiß es. Es nützt Dir überhaupt nichts, wenn Deine Daten einen Meter weiter ungepuffert aus Deinem Programm kommen und an der ersten Straßenecke, auf die Du keinen Einfluß mehr hast, dann doch gepuffert werden.

          Du hast REcht, es klappt auch nicht. Auch der bereits mehrfach angesprochene "Trick", die STDOUT einfach zu schließen (um die Übertragung zu erzwingen) ist ein Schuß in den Ofen, weil der Apache dann sofort das ganze Script terminiert.

          Dein Problem ist nicht Perl, sondern HTTP.

          Wichtig ist nur, daß der Benutzer merkt, es tut sich was und das er nicht den länger werdenden Balken unten im Browser für eine Fehlfunktion des Programms hält!

          Und genau das geht mit HTTP nicht.

          Und genau das geht. Irgendwie. siehe http://www.suchen.com . Und auch verschieden Chats verwenden eine offene Datenübergabe um nur einzelene ZEilen zu übertragen.

          Was Du willst, das ist eine stehende Verbindung - also verwende ein Kommunikationsprotokoll, welches diese ermöglicht (schreibe ein Java-Applet und programmiere Deine Kommunikation selbst oder was auch immer).

          Ich hatte nur gehofft, daß dieses PRoblem so allgemein ist, daß eben diese Lösung bereits schon jemand gemacht hat und es als Modul geladen und verwendet werden könnte. War wohl aber nicht. Auch hier bei Selfhtml hatte man dieses Problem vor einigen Jahren (und ich kann nirgendwo eine Lösung sehen)...

          Viele Grüße
                Michael

          Ja, Gruß und Danke Dir trotzdem!

          Martin

          1. Hi Martin,

            Und genau das geht mit HTTP nicht.
            Und genau das geht. Irgendwie. siehe http://www.suchen.com.

            Du kannst Dir selbst ansehen, was die tun:
            http://forum.de.selfhtml.org/cgi-bin/http_trace.pl?url=http%3A%2F%2Fsuchen.com%2Fsearch%2F%3Fq%3Dmod_gzip%26method%3Dall%26delay%3D5%26page%3D20%26hits%3D20%26engines%3Don%26us-altavista%3DON%26us-alltheweb%3DON%26us-teoma%3DON%26de-qualigo%3DON%26de-yahoo%3DON%26de-dmoz%3DON%26de-witch%3DON%26de-abacho%3DON%26de-hrdaten%3DON%26x%3D48%26y%3D13&method=GET&version=HTTP%2F1.1

            Ich vermute, die Angabe
                Transfer-Encoding: chunked
            führt in die Richtung, in welche Du willst.

            Aber nicht mal Christians Skript kann darstellen, was tatsächlich noch alles gesendet wird - weil HTTP nun mal _eine_ Response auf _eine_ Anforderung erwartet.

            Und auch verschieden Chats verwenden eine offene Datenübergabe um nur einzelene ZEilen zu übertragen.

            Tun sie das wirklich, oder glaubst Du das nur?

            Du willst offenbar "HTTP Push" (als Suchbegriff) - aber frag mich besser nicht, welche Browser (und Proxies und ...) das unterstützen und was man dazu auf dem Server machen muß (ich habe das auch schon versucht - falls Du da weiter kommst als ich, würden mich Details interessieren).

            Ich hatte nur gehofft, daß dieses PRoblem so allgemein ist, daß eben diese Lösung bereits schon jemand gemacht hat

            Durchaus.
            Es gibt Alternativen zu HTTP. Du mußt nicht versuchen, die Dose mit dem Schraubenzieher zu öffnen.

            Beispielsweise ist auch das "KeepAlive"-Konzept etwas, das vage in Deine Richtung geht - auch dort ist die Idee, eine stehende Verbindung dazu zu verwenden, um mehrere Dinge zu übertragen, die von einem einzelnen HTTP-Request zumindest "ausgelöst" wurden.

            Aber HTTP ist kein Telefon, es ist ein Postkartenversand. Dein Versuch, daraus ein Telefon zu machen, muß scheitern. Für stehende Verbindungen gibt es andere, geeignetere Protokolle.

            Viele Grüße
                  Michael

            --
            T'Pol: I apologize if I acted inappropriately.
            V'Lar: Not at all. In fact, your bluntness made me reconsider some of my positions. Much as it has now.
            (sh:| fo:} ch:] rl:( br:^ n4:( ie:% mo:) va:| de:/ zu:| fl:( ss:) ls:~ js:|)
             => http://www.peter.in-berlin.de/projekte/selfcode/?code=sh%3A|+fo%3A}+ch%3A]+rl%3A(+br%3A^+n4%3A(+ie%3A%25+mo%3A)+va%3A|+de%3A%2F+zu%3A|+fl%3A(+ss%3A)+ls%3A~+js%3A|
            Auch diese Signatur wird an korrekt konfigurierte Browser gzip-komprimiert übertragen.
    2. Halihallo Philipp,

      autoflush ($|=1;) alleine bringts nicht, Suchalgorithmus zu verbessern geht fast auch nicht mehr(habe bereits jetzt bis zu 50 URL-Requests in 10 Sekunden abgearbeitet; siehe http://www.ehandel.de/cgi-bin/schnapper.pl, was ich nicht im Griff habe, sind die Antwortzeiten der fremden Suchmaschinen, bzw die timesouts.

      Mir schwebt sowas vor wie bei http://www.suchen.com, wo man "zusehen" kann, wie er schafft und was eintrudelt...

      Ich gebe Die Frage nochmals an alle und bedanke mich für weitere Anregungen schon jetzt ganz herzlich!

      Gruß!
      MArtin

      1. Halihallo Martin

        autoflush ($|=1;) alleine bringts nicht, Suchalgorithmus zu verbessern geht fast auch nicht mehr(habe bereits jetzt bis zu 50 URL-Requests in 10 Sekunden abgearbeitet; siehe http://www.ehandel.de/cgi-bin/schnapper.pl, was ich nicht im Griff habe, sind die Antwortzeiten der fremden Suchmaschinen, bzw die timesouts.

        Nun, da lässt sich am Algorithmus nicht viel schrauben, da hast du recht.

        Mir schwebt sowas vor wie bei http://www.suchen.com, wo man "zusehen" kann, wie er schafft und was eintrudelt...

        Ich kann mir nur vorstellen, dass die ihren Webserver so konfiguriert haben, dass die
        Packages (die Daten werden ja über Chunks mit gewisser Länge übertragen) klein sind und
        sofort versendet werden. Ich wüsste jedoch nicht, wie man dies tun könnte.

        Da ich keine weiteren "schönen" Vorschläge mehr habe, bleibt mir nur den Vorschlag zu
        unterbreiten, dass du dir einer Weiterleitung behilfst. Die Suchabfrage mit den Childs
        werden in einer Datei gepuffert, STDOUT wird jedoch gleich nach der Meldung
        "bitte warten" geschlossen. Und wenn die Weiterleitung anspringt, wird die zuvor
        generierte Datei ausgegeben (welche nun ja die Suchergebnisse enthält). Schön finde ich
        dies zwar ebensowenig wie du wahrscheinlich, aber es ist im Moment das einzige, was mir
        noch einfällt (ein eigener HTTP-Daemon der an Port 80 lauscht und die Daten ad-hoc aus-
        gibt fällt wohl aus, nehme ich an?).

        Das Problem ist schlicht dies, dass HTTP nicht dafür gedacht ist. In HTTP ist die
        kleinste Sinneseinheit meinetwegen die Ressource und diese ist entweder übertragen oder
        nicht. Teilstati gibt es _eigentlich_ nicht. Klar kann man es versuchen, klar gibt es
        "Lösungen", aber alle sammt sind nicht im Sinne des HTTP. Aber ich glaube, das weisst
        du bereits.

        Viele Grüsse

        Philipp

        --
        RTFM! - Foren steigern das Aufkommen von Redundanz im Internet, danke für das lesen der Manuals.
        Selbstbedienung! - Das SelfForum ist ein Gratis-Restaurant mit Selbstbedienung, Menüangebot steht in den </faq/> und dem </archiv/>.
        1. Halihallo Philipp

          Da ich keine weiteren "schönen" Vorschläge mehr habe, bleibt mir nur den Vorschlag zu
          unterbreiten, dass du dir einer Weiterleitung behilfst. Die Suchabfrage mit den Childs
          werden in einer Datei gepuffert, STDOUT wird jedoch gleich nach der Meldung
          "bitte warten" geschlossen. Und wenn die Weiterleitung anspringt, wird die zuvor
          generierte Datei ausgegeben (welche nun ja die Suchergebnisse enthält).

          Ich habe mich eigentlich nicht getraut, STDOUT vorzeitig zu schliessen, weil der Apache da sehr unwirsch reagiert ("...Schließlich - und das ist meines Wissens nirgendwo dokumentiert (bin mal böse drauf reingefallen) - sollte man in einem CGI nachdem man die Webseite ausgegeben hat niemals STDOUT schließen. (Ich hatte mir gedacht, ich könnte dem Webserver so mitteilen, daß das Dokument fertig ist und er deswegen nicht darauf warten muß, daß das Script terminiert, weil es nur noch einige Aufräumarbeiten erledigt. Dummerweise killt der Apache ein CGI, wenn dessen STDOUT geschlossen wird. Muß man wissen.)... aus http://www.cip.physik.uni-muenchen.de/~tf/perl/lektion7.html

          Die childs arbeiten sowieso gepuffert (geht dort mit pipeorienterten Jobs nicht anders, besonders wenn die ANtwort gut gemischt zurückkommt, aber sortiert gebraucht wird).

          Ich werde das mit dem STDOUT schließen mal ausprobieren...

          Danke und viele Grüße!

          Martin