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

Hi colleague!

Problem

I develop an application with web intrface for my company. That application includes Perl classes and Embperl scripts. There are some places which take much time to retrieve results. So, I need to display for user some helpful message like 'Please wait' or animation picture which imitate progress bar.

Solution

I've found and stydied merlyn's solution Watching long processes through CGI. But I've decided to go by other way. My choise was occasioned following reasons:

So, I've implemented a following logic: if user call some of long running operations, request is passed to the special page - wait page. That page is Embperl script which displays helpful message, parses request arguments and does redirect to the target script (defined as request parameter) which execute long running operation.
So, the user watches display message untill that operation is not finished (Embperl is not flush buffers). Than result page loads and the user can see results.

I'd like to know your opinion about that solution. Thanks in advanced.

~ Schiller

Replies are listed 'Best First'.
Re: Watching long processes through HTTP
by perrin (Chancellor) on Apr 21, 2004 at 18:08 UTC
    You can turn off buffering with Embperl. Look at the optEarlyHttpHeader option.

    I really can't tell what you did from your description. If you did a redirect, then the user is just being sent to the slow page.

      Sorry for my English. My description is not clear. Let's see how it works.

      1)

                         +-------------------------------+
                         |  SERVER                       | 
      +----+  Request    |  +----------+   +-----------+ |
      |User|--------------->| Target   |-->|   Perl    | | 
      |    |             |  | Embperl  |   |  class    | | 
      |    |<---------------| script   |<--|           | |
      +----+  Responce   |  +----------+   +-----------+ |
                         |                               |
                         +-------------------------------+ 
      
      In this case, user'll see current page till then requested function returns results and new page will be generated. Because In Embperl 2 there is no way to flush buffers before everything is done - this is answer of Gerald Richter (man who develops Embperl).
      So, I'd just want to display for the user some helpful message.

                         +-------------------------------+
                         |  SERVER                       | 
      +----+  Request    |  +----------+                 |
      |    |--------------->|  Wait    |                 |
      |USER|             |  |  page    |                 |
      |    |<---------------|          |                 |
      +----+  Responce   |  +----+-----+                 |
         ^     (wait)    |       | Redirect              | 
         |               |       v                       |  
         |               |  +----------+    +---------+  |
         |               |  |  Target  |--->| Perl    |  |
         +------------------| script   |<---| class   |  |
            Respoce      |  |          |    |         |  |
             (result)    |  +----------+    +---------+  |
                         +-------------------------------+ 
      
      In this case, user calls wait page which display some message (and user can see it immediately because it's short request). Then wait page parses passed arguments, builds new request (target script name should be passed as argument) and does redirect to target script.
      So, the user watches wait page message till then long running operation will be finished and result page will be generated.

      ~ Schiller

        You didn't mention that you were using Embperl 2 before. Embperl can flush buffers, but Embperl 2 is a totally different system.

        What's confusing about your diagram is what you mean by "redirect" in #2. If you are doing a standard HTTP redirect, the browser will simply load the other page immediately, not wait until it finishes. Maybe you are actually doing an internal fetch of some kind with LWP or an internal redirect?

        The forking approach that merlyn described is a bit more complex, but better for scalability. The reason is that your approach will tie up an apache child process during the generation of the slow page, while the forking approach forks off the worker process and leaves the apache child free to handle more web requests.