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

Hi --

I have web page foo.html which may or may not exist. If it doesn't, a Mason dhandler jumps in to build it, then redirects over to it. This works.

The user gets just waits while the page builds. To the user, the delay seems like an inexplicably long page load time with no progress.

How could, in Mason, send out a visible page stating "Please wait while page builds...", then automatically redirect over to the correct page when it was ready?

Better, how might I send incremental progress messages to the browser "Building page...", "Foozle build completed...", "Woozle build completed...", "Page built, redirecting (click here if browser doesn't redirect on its own)"

Thanks

water

Replies are listed 'Best First'.
Re: Mason: Please Wait While Generating
by davidrw (Prior) on Jul 18, 2005 at 20:21 UTC
    The general approach from this article by merlyn can be applied here i think (from this thread: CGI::Application timeout). Basically your building needs to be forked off, and then your "Please wait" screen refreshes to a handler that checks if the process is done, and goes there when it is done. It can also check progress (maybe check filesize or whatever depending on what the build does).
      Mind you that N refreshes to your app can happen from this and those N runs can make the generation that much slower than just waiting for the page to be generated. What is taking so long to generate the page in the first place? Is the server underpowered?


      -Waswas
        Mind you that N refreshes to your app can happen from this and those N runs can make the generation that much slower than just waiting for the page to be generated.
        If a simple probe to tell if it's ready or not makes your app go "much slower", then you haven't quite designed it right. Gotta keep the probe cheap.

        -- Randal L. Schwartz, Perl hacker
        Be sure to read my standard disclaimer if this is a reply.

Re: Mason: Please Wait While Generating
by cowboy (Friar) on Jul 18, 2005 at 21:08 UTC
    I do something similar to what you are asking using mason's cache as a flag to say it's being built.
    my $page = $m->dhandler_arg; # do sanity checking ... unless ($m->comp_exists($page)) { unless ($m->cache->get($page)) { # see if we're building it already $m->cache->set($page,'1','60 sec'); # set a flag to say we're buil +ding it $m->comp("/building_page"); # please wait page $m->flush_buffer; # flush the output # here we begin building the page $m->comp("/build_page", $page); } $m->comp("/building_page"); $m->flush_buffer; } </%init>

    The building page, would spit up a simple note saying it's processing, and a meta-refresh tag so the client re-requests it in a moment. A little css/javascript can be used to add some animation to keep them amused.

    (code above is untested, but should get you going in the right direction)

      Thanks, cowboy, this looks great.

      I don't follow all of it, though.

      Is there an automatic redirect to the finished page? Or is the user just instructed to hit refresh after waiting a bit on the building_page component?

      thanks

      water

        I basically print out a very light 'Loading' type page, which has a meta-refresh tag to tell the client to re-request it in a few seconds.

        If it has completed whatever work it needs to do (in my case, execute a heavy database query and collect results, then cache them), it then displays the results (which are now in the cache), if it hasn't completed it, it spits up the 'Loading' page again, set to refresh again.

        (update:) The basic logic is as follows:
        if (page_is_in_cache) { display page. } elsif (flag_is_in_cache) { page is being rendered, display a 'loading' message with a meta refr +esh } else { set_flag_in_cache display loading page render page stuff page in cache clear flag in cache }