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

Hi,

I'm using CGI::Application for a web app and would like to know if anyone has been able to figure out how to flush the output to the browser in the middle of a run mode?

Basically the situation is this: I have a function that can take about 20 seconds to complete. I would like to show some type of output prior to the function completing.

Any ideas?

Jason L. Froebe

No one has seen what you have seen, and until that happens, we're all going to think that you're nuts. - Jack O'Neil, Stargate SG-1

  • Comment on CGI::Application... flushing output to browser?

Replies are listed 'Best First'.
Re: CGI::Application... flushing output to browser?
by antirice (Priest) on May 22, 2004 at 22:44 UTC

    I faced this problem as well and here's what I ended up doing:

    sub irregular_run_mode { my $app = shift; $app->header_type("none"); $| = 1; print $app->query()->header(); # code here return ""; }

    Yeah. It tends not to work too well if you use cgiapp_postrun to alter the output. Of course, you can fix that with:

    sub cgiapp_postrun { my ($app,$outref) = @_; return $outref if $app->get_current_runmode() eq "irregular_run_mode +"; # ... }

    Note: I consider this to a be a hack and rather ugly. Please leave comments so if someone wishes to alter the irregular_run_mode so it works normally they will know that they need to alter cgiapp_postrun as well.

    antirice    
    The first rule of Perl club is - use Perl
    The
    ith rule of Perl club is - follow rule i - 1 for i > 1

      I too face this problem, and tried your hack above.

      It works as long as I don't have to use the Authentication plugin. With Authentication plugin, it seems that any irregular mode that is protected by the plugin can never be displayed. Whenever you try to go to that mode, you get the login box, and even if you enter the right credentials, you get to the login box again.

      I haven't quite figured out why yet, but I think it's because session state is transmitted by cookies, which themselves are transmitted through http headers. And the specific cookie headers generated by Authentication plugin are not available until AFTER the body has been generatied (the cookie headers are being generated by a postrun hook for some strange reason). In a standard runmode that doesn't matter, because the headers are prepended to the body before the whole thing is outputted. But with an irregular mode, you need to generate and print the headers before you generate and print the body.

      Has anybody solved this problem?

Re: CGI::Application... flushing output to browser?
by BUU (Prior) on May 22, 2004 at 20:21 UTC
    You can't do that with out totally subverting the process of CGI::Application. You have to return all the output at the end of the run mode. You could of course just use "print" statements, but then it'll mess up the rest of your output and so forth.

    The best way I see is to redirect to a non cgi::app cgi file that can print it out slowly over 20 seconds and then redirect back to your run mode or something.
Re: CGI::Application... flushing output to browser?
by Zaxo (Archbishop) on May 22, 2004 at 20:38 UTC

    You can flush output by closing STDOUT as soon as you've printed everything you mean to. The client then thinks the script is done, and you're free to continue processing.

    Added: Hmm, take that as a general statement - it doesn't seem to fit in with the CGIA way.

    After Compline,
    Zaxo

      Just for other people's notes, the CGI::Application way would be to return the page's text or a reference to it at the end of your script and then C'A takes care of the task of sending the http headers and page to the browser. You are normally expected to not print.

        Yup, I've pretty much decided to write a short disclaimer: may take a little while or similar.

        Thanks everyone!

        No one has seen what you have seen, and until that happens, we're all going to think that you're nuts. - Jack O'Neil, Stargate SG-1