in reply to Managing a long running server side process using CGI
After reading through the various previous replies and the linked material I put together the following two test applications. The CGI app is heavily based on the sample code in merlyn's LinuxMag column Watching long processes through CGI (pointed to by McDarren++), with amendments so that it works under Windows (but no longer under *nix, although making both work in this "framework" ought be trivial). In the real application the CGI app would manage the monitored app by writing to a second file.
The managing app:
#!Perl -w use strict; use CGI::Pretty qw(:standard :cgi-lib); use CGI::Carp qw(fatalsToBrowser); # Remove for production code use File::Cache; $CGI::DISABLE_UPLOADS = 1; # Disable uploads $CGI::POST_MAX = 10240; # Maximum number of bytes per post $| = 1; # Unbuffered output if (param('Spawn')) { # setup monitoring page then spawn the monitored process my $session = get_session_id(); my $cache = get_cache_handle(); $cache->set($session, "wait ..."); # no data yet Delete_all(); # parent redirects browser to monitor session param('session', $session); print redirect (self_url()); close STDOUT; # Rest of this block alters in *nix context to spawn monitored pro +cess use Win32::Process; my $job; Win32::Process::Create ( $job, 'c:/Perl/bin/perl.exe', "perl.exe spawned.pl $session", 0, NORMAL_PRIORITY_CLASS | DETACHED_PROCESS, '.' ); exit 0; # all done } elsif (my $session = param('session')) { # display monitored data my $cache = get_cache_handle(); my $data = $cache->get($session); if (! $data) { # something is wrong showError ("Cache data not available"); exit 0; } my $headStr = $data eq 'Completed' ? '' : "<meta http-equiv=refres +h content=5>"; print header(); print start_html (-title => "Spawn Results", -head => [$headStr]); print h1("Spawn Results"); print pre(escapeHTML($data)); print end_html; } else { # display spawn form print header(), start_html("Spawn"), h1("Spawn"); print start_form(); print submit('Spawn', 'spawn'); my %params = Vars (); for my $param (keys %params) { print br ("$param -> $params{$param}"); } print end_form(), end_html(); } exit 0; sub showError { print header(), start_html("SpawnError"), h1("Spawn Error"); print p (shift); my %params = Vars (); for my $param (keys %params) { print br ("$param -> $params{$param}"); } print end_html(); } sub get_cache_handle { File::Cache->new ({ namespace => 'Spawn', username => 'nobody', default_expires_in => '30 minutes', auto_purge_interval => '4 hours', }); } sub get_session_id { require Digest::MD5; Digest::MD5::md5_hex(Digest::MD5::md5_hex(time().{}.rand().$$)); }
The monitored app:
#!Perl -w use strict; use File::Cache; my $session = shift; my $cache = get_cache_handle(); $cache->set($session, "wibble ..."); # no data yet my $end = time () + 20; my $count = 0; while (time () < $end) { $cache->set ($session, "Count: $count\n"); ++$count; sleep (1); } $cache->set ($session, "Completed"); exit 0; # all done sub get_cache_handle { File::Cache->new ({ namespace => 'Spawn', username => 'nobody', default_expires_in => '30 minutes', auto_purge_interval => '4 hours', }); }
The code was tested using a local Apache server and seems to provide exactly the types of interaction I am looking for.
Are there any glaring oversights?
|
---|
Replies are listed 'Best First'. | |
---|---|
Re^2: Managing a long running server side process using CGI
by GrandFather (Saint) on Feb 26, 2007 at 10:49 UTC | |
Re^2: Managing a long running server side process using CGI
by Anonymous Monk on Nov 22, 2015 at 06:52 UTC |