http://www.perlmonks.org?node_id=635010

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Dear monks,

I had a question about client pull does not work and one of the monk here gave me the code and I tried it but it does not seem to work. Would someone tell me why? I need it to jump to another page after 3 seconds, not 30 seconds after which the perl script is done. Thanks

Client Pull Not Working correctly

#!/usr/bin/perl use CGI qw(:standard); $| = 1; if ($pid = fork) { print "Content-type: text/html\n\n"; print '<HEAD>'; print '<META HTTP-EQUIV="Refresh" CONTENT="3; URL=/cgi_data/page1.ht +ml">'; print '<TITLE>New Site notification</TITLE>'; print '</HEAD>'; print '<BODY>'; print 'My homepage has moved to a new location. '; print '</BODY>'; print '</HTML>'; close STDOUT; exit; } else { close STDOUT; sleep 30; exit; }

Code tags added by GrandFather

Replies are listed 'Best First'.
Re: close STDOUT does not work, why?
by BrowserUk (Patriarch) on Aug 25, 2007 at 04:05 UTC

    Try closing STDIN and STDERR also.

    It's probably dependant upon the webserver you are using, but the one I'm playing with doesn't seem to let go of the perl script and send the html until all three shared handles are closed. YMMV with other webservers, but it's worth a shot.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Yep, that did the trick. Thanks a lot BrowserUk.
      Ditto! :) Thanks.
      Yep, that did the trick. Thanks a lot BrowserUk. Now if I can get my server push to work correctly.
        Now if I can get my server push to work correctly.

        Sorry, I can't help you there.

        I don't see how the script can continue to send 'multipart/x-mixed-replace' content after it has closed the handles to get the webserver to let go? Thinking about it, I guess it might be possible to fool the webserver by duping STDOUT etc. before closing the originals. I haven't tried that, it just came to me.

        I've been playing around with client pull for long running processes and found that the best way (on Win32) was to open a new socket, start a new process that inherits the open handles, redirect the browser to that new socket and have the original cgi script terminate. The spawned process then runs as a very limited html daemon responding to client pull requests on a thread with updated status information until the long running process has finished. I can then deliver the final status/output and die.

        The thing I like about this is that it removes the client pull from the webserver, and also allows the long running process to detect if the client goes away, and terminate early if it does.

        But take all that with a huge handful (bucketful) of salt because literally all I've done is play with it. I've never tried using it for real.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: close STDOUT does not work, why?
by f00li5h (Chaplain) on Aug 25, 2007 at 10:08 UTC
      Hi Merlyn,

      Your example at Watching long processes through CGI (Aug 02) does not work if a person is running Apache ver 2.0 or later. I searched the web for the solution to this problem for awhile and found many references to your page and in other forums people also mentioned your example only prints out all the outputs when the Perl script finished but not while it is running. It would be helpful for others if somehow your example could be updated and include
      close STDIN;
      close STDERR;
      and reopens these standard IOs to NULL to make it work for later version of apache.
      Thanks for the reference though.

        Where are you suggesting those closes be put? perhaps as a diff/patch against the code listing or some line numbers would clarify your intent...

        It works as expected for me, when run as CGI in my userdir on Apache2, perhaps you're having issues with mod_perl or some other configuration issues?

        Running:

        @_=qw; ask f00li5h to appear and remain for a moment of pretend better than a lifetime;;s;;@_[map hex,split'',B204316D8C2A4516DE];;y/05/os/&print;

Re: close STDOUT does not work, why?
by MelaOS (Beadle) on Aug 25, 2007 at 03:24 UTC
    HI if you wanted it to move after three seconds, then you should change the sleep 30 to 3 instead.thanks.
      Actually the child will go on to run some long process. I put the sleep 30 there to simulate this long process. The parent print the HTML page and every time it refreshes, it will get new data from the new page that the child printed.