Hi Guys, I wanted to say thank you for your support and ideas.
I did not find something that I liked as much as to adopt it right away. So, I wrote my own module for this, which will, no duobt, evolve some more. I may open source it. The way it works is as follows: 1) The initiating web page starts a long task by executing a call to start_long_task, passing it a ref to a subroutine to be executed that could take a long time. A few things happen: * Process forks * Output to STDOUT is redirected to a variable * An IFRAME tag is output, pointing to the monitoring script (see below). * The subref is executed * When it finishes, it writes the output from the variable to file /tmp/longtask.<taskid> 2) The monitoring script is a two liner: #!/usr/bin/perl use LongWebTask; serve_long_web_task; serve_long_web_task is the subroutine that handles everything. * The monitoring script is watching the output in /tmp/longtask.<taskid> file. It keeps refreshing the iframe content until it finds said file, at which point it outputs its content and deletes temporary files. I am including the source here, but it is a work in progress. I would like to hear comments as to whether this would be appropriate for CPAN. I have another module there called Net::eBay. #!/usr/bin/perl use strict; use warnings; package LongWebTask; use Time::HiRes qw( gettimeofday ); use Digest::MD5 qw( md5_hex ); use CGI; use File::Slurp; use strict; require Exporter; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); @ISA = qw(Exporter); $VERSION = 2000.0821; @EXPORT= qw( start_long_web_task serve_long_web_task ); sub start_long_web_task { my ($cgi, $options, $subref, @args) = @_; my $progress_url = $options->{progress_url} || die "progress_url parameter not defined, cannot create iframe"; my $refresh_frequency = $options->{refresh_frequency} || 10; my ($seconds, $microseconds) = gettimeofday; my $randstr = $$ . $seconds . $microseconds . rand( 1E9 ); my $jobid = md5_hex( $randstr ); my $iframe_width = $options->{iframe_width} || "90%"; my $iframe_height = $options->{iframe_height} || "1000"; print "<IFRAME SRC=\"$progress_url?jobid=$jobid\&action=show\" WIDTH=$iframe_width HEIGHT=$iframe_height></IFRAME>"; if ( fork ) { # Parent } else { # Child my $output = ""; close STDOUT; open STDOUT, ">", \$output; my $rc = &$subref( @args ); close STDOUT; my $outfn = outputfn( $jobid ); write_file( "$outfn.new", $output ); rename( "$outfn.new", $outfn ); exit( $rc ); } } sub outputfn { my ($jobid) = @_; return "/tmp/longtask.$jobid.output"; } sub progressfn { my ($jobid) = @_; return "/tmp/longtask.$jobid.progress"; } sub serve_long_web_task { my $cgi = new CGI; my $jobid = $cgi->param( 'jobid' ) || die "$0: Parameter jobid is not defined in serve_long_web_task"; my $action = $cgi->param( 'action' ) || die "$0: Parameter action is not defined in serve_long_web_task"; $jobid =~ /^\w+$/ or die "Job id is illegal: '$jobid'"; if ( $action eq 'show' ) { print $cgi->header; my $outfn = outputfn( $jobid ); if ( -e $outfn ) { print read_file( $outfn ); unlink( outputfn ( $jobid ) ); unlink( progressfn( $jobid ) ); } else { print $cgi->start_html( '-head' => $cgi->meta( { -http_equiv => 'Refresh', -content => 3, } ), ); print "Job is in progress. <BR>\n" . `date `; } } } 1;