Jason Minton
asked on
Fork Perl CGI sub into background and wait for it to finish.
I have a Perl CGI script and I have sub that I'm calling that takes a very long time to run. It takes so long that the web browser times out and the process dies before it finishes.
I need to fork this sub routine into the background somehow, then display a page that says something like 'processing...' and this page keeps refreshing and checking to see if the process has completed.
1. How can I push a perl subroutine into the background so it will run to completion.
2. How can I check to see if the background process has completed?
3. Need to do all of this for CGI web app.
Thank you!
I need to fork this sub routine into the background somehow, then display a page that says something like 'processing...' and this page keeps refreshing and checking to see if the process has completed.
1. How can I push a perl subroutine into the background so it will run to completion.
2. How can I check to see if the background process has completed?
3. Need to do all of this for CGI web app.
Thank you!
ASKER
Thank you, I will give this a try today.
This is running on an IBM AIX (Unix) system.
This is running on an IBM AIX (Unix) system.
ASKER
Currently in my SlowSub I check a lot of things for errors and if it failes I return from the sub with some error code... If I'm running SlowSub as a child process, I'm assuming I can't use return, only exit. Is there someway I can detect that it exited due to an error instead of success?
I guess I could write some type of file somewhere and check for that, but is there a better way?
thx!
I guess I could write some type of file somewhere and check for that, but is there a better way?
thx!
If it is possible for your SlowSub to do some error checking quickly, then you could have it only fork if thinks okay.
But the child will not be able to write to the web browser, anything it prints on STDOUT or STDERR will not be seen. Logging to a file is the most common method.
But the child will not be able to write to the web browser, anything it prints on STDOUT or STDERR will not be seen. Logging to a file is the most common method.
ASKER
I guess I'm doing this wrong... can you tell me?
my $forked = copyProdToDevView($p{'view _id'});
sub copyProdToDevView($)
{
my $view_id = shift;
my %msg;
$msg{'ERR'} = 0;
# this can take a long time, so run it as a child process
my $pid = fork;
if (!defined($pid))
{
$msg{'ERR'} = 1;
$msg{'TXT'} = qq{Could not create child process for data import into view. $!};
return \%msg;
}
else
{
$msg{'TXT'} = $pid;
return \%msg;
}
my $dbhP = dbconnect('scully');
my $sql_P_edit_type = qq{
select type_id,
name,
sequence
from ${dbtablePrefix}_ec_edit_t ype
where view_id = ? };
my $sql_D_edit_type = qq{
insert into ${dbtablePrefix}_ec_edit_t ype
(type_id, name, sequence, view_id)
values(?, ?, ?, ?) };
$dbhP->disconnect();
exit;
}
my $forked = copyProdToDevView($p{'view
sub copyProdToDevView($)
{
my $view_id = shift;
my %msg;
$msg{'ERR'} = 0;
# this can take a long time, so run it as a child process
my $pid = fork;
if (!defined($pid))
{
$msg{'ERR'} = 1;
$msg{'TXT'} = qq{Could not create child process for data import into view. $!};
return \%msg;
}
else
{
$msg{'TXT'} = $pid;
return \%msg;
}
my $dbhP = dbconnect('scully');
my $sql_P_edit_type = qq{
select type_id,
name,
sequence
from ${dbtablePrefix}_ec_edit_t
where view_id = ? };
my $sql_D_edit_type = qq{
insert into ${dbtablePrefix}_ec_edit_t
(type_id, name, sequence, view_id)
values(?, ?, ?, ?) };
$dbhP->disconnect();
exit;
}
ASKER
That makes sense, I will use file logging or maybe use a db table... I guess I just need help with the above now...
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
2. You can check the running processes to see if it is still running. This will be OS dependent. Which OS are you running? You would use ps on unix.
3. This should work within a CGI app.
eg:
#doing stuff....
SlowSub();
#do more stuff
sub SlowSub {
#Call fork
my $pid=fork;
#Display error message if not successful
die "Could not fork: $!\n" unless defined($pid);
#parent returns immediately
return if $pid;
#Only child runs here
#Do stuff that is slow
#Child exits
exit;
}