Spawning an independent process from a perl CGI script

I have a perl CGI script which is ofcourse called under user "nobody". I want this script to update a database. This information needs to come from various sources which may take a while to find. I therefore want to make the updating of the database a seperate process so that the CGI script can exit while the updating process does its work. The CGI script is meant as a way of starting the process going, and MUST be independent of the updating process. I have tried the following;

1) use system with the & appended. The script does not finish until ALL processes, even child processes end (because they all run under "nobody"). This is no good.
2) Use exec to try to create a child process. This runs afoul of the same problem, the CGI script will not end until all processes owned by nobody are complete.

This led me to think of the following  possible solution;
1) Use Perl Cookbook recipe 16.11 to make a process look like a file and have the CGIs try to update a file which is really a script which updates the database. Would this new process also be owned by nobody?
2) Use IPC::Shareable to share a variable between the CGI script processes and another process which I have running constantly under a different user (say myself). This process is sleeping and reacts only ehen a variable changes (I read about this in Perl Cookbook, recipe 16.12) This should allow for an exchange of data between the two processes (I only need two variables to go from the CGI to the process which updates the database). I am concerned whether IPC::Shareable will allow processes owned by different users to share variables...


I would appreciate it if someone could give me a suggestion here. I know this is a complicated problem so I am really looking for an idea and a direction to follow. Links to documentation or a book where I can get this information would be great. Obviously the more info you can give, the better, and sample code would be the best!

Thanks,

Elam Birnbaum
Phone2Networks
elambAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

ventolinCommented:
Complete Dissociation of Child from Parent:

In some cases like yours, you'll want to complete dissociate the child process from the parent. The easiest way is to use:

    use POSIX qw(setsid);
    setsid()            or die "Can't start a new session: $!";

However, you may not be on POSIX. The following process is reported to work on most Unixish systems. Non-Unix users should check their Your_OS::Process module for other solutions.

Open /dev/tty and use the TIOCNOTTY ioctl on it. See tty(4) for details.

Change directory to /

Reopen STDIN, STDOUT, and STDERR so they're not connected to the old tty.

Background yourself like this:

    fork && exit;

Ignore hangup signals in case you're running on a shell that doesn't automatically no-hup you:

    $SIG{HUP} = 'IGNORE';       # or whatever you'd like

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
elambAuthor Commented:
Yes, this is verbose out of the Perl manual, but it doesn't explain what I need to do. I am on Linux, so it is POSIX. So I can use those two lines, but where do I put them, in the child or parent program? How do I call the child process? I am currently using;
system("program &");
Is this correct, or do I have to use another method?

I tried putting these lines in both the child and the parent with no success. Do I need to provide an argument for setsid? I kind of need more info.

Elam
0
ventolinCommented:
use POSIX;

# fork and exit

if ($pid = fork) {
        # we are the parent
        # cgi returns that we have started
        print qq!we have forked sir!;
        }
else {
        POSIX::setsid();
        # your long data retrival stuff here
        system("echo 'test' > test.txt");
 }



you said you have the cookbook, so check out 17.15 on pg 634
0
elambAuthor Commented:
Yes, I did check out this perl recipe. Unfortunately, it still doesn't work. When you call the script, you see all the data displayed, but the Netscape (or IE) icon continues to animate until all processes, even those that have supposedly become independent of their parents, are complete. I verified this by displaying a top and the moment all scripts owned by nobody (spawned by that particular script call) are complete, the animation ends.

I suspect, however, that this may be something that our Apache web server does (perhaps as some sort of security concern, or some sort of anti-zombie process). There are so many setting for Apache, its not inconceivable that it controls all processes spawned by scripts called from it even using the daemon trick above.

I have, however, solved the problem using a different approach. I utilized the daemon code in the perl recipe you refered to to create a standalone daemon (running under root and added to the list of daemons starting up automatically as the machine boots), which opens a socket connection. The CGI scripts, then send data to this daemon which then spawns off the required processes. Since the CGI script is only opening a socket, sending a trivial amount of data, then closing the socket, the script finishes almost immediately while the daemon deals with updating the database at its leisure.

This solution is not as ideal as the one  I tried to do above, since this solution requires the creation of a daemon which is constantly running, but it works! I am giving you the points, since the code did end up in my solution, though not in the way I intended. If you think my original idea is still possible, I would greatly appreciate it if you e-mailed me with any ideas you have (I'm not sure if you're familiar with Apache) at elam@phone2networks.com

Thanks for all your help!

Elam Birnbaum
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Perl

From novice to tech pro — start learning today.