You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Anton Permyakov <an...@mail.ru> on 2003/04/22 07:50:25 UTC

Re[1]: Problems with lingering process invoking from mod_perl

Hi Stas,

----- Original Message -----
From: "Stas Bekman" <st...@stason.org>
To: "Anton Permyakov" <an...@mail.ru>
Cc: <mo...@perl.apache.org>
Sent: Tuesday, April 22, 2003 6:01 AM
Subject: Re: Problems with lingering process invoking from mod_perl

> > after this i have to refresh client's page in order to show him number
of
> > downloaded already news.
> > So, in session i can store PID of my
> > /usr/local/apache/htdocs/perl/getting_news.pl and i can check the state
of
> > it with
> > kill 0, $CHILDPID
> >
> > But some times it doesn't work. Process of getting news may be finished
> > suddenly (when still there are undownloaded news in the group) or may do
not
> > start even. I don't know why.
>
> I suppose that this doesn't work when the child has quit. You can fork a
> process A, which will fork the real process B that will do the job and A
will
> waitpid on B. Since A does nothing but tracking B, it's probably the most
> robust way.

Stas, thank you,
and what do you think if i will not do fork (since it is not so good under mod_perl), but try:

1. Do redirect user to another page from Apache's child.
2. Remember PID of this Apache's child in DataBase.
3. Invoke job by exec() directly in this child (is it possible to send
answer to client and invoke exec() after this in the same child? i mean the
client should not be wait finish of exec()).
4. From redirected (in 1.) page (in any children, it doesn't matter) i will
check the state of job with PID from the DataBase

I think it should work, what do you think?

Anton Permyakov,
Soludium.com

Re: Problems with lingering process invoking from mod_perl

Posted by Stas Bekman <st...@stason.org>.
Anton Permyakov wrote:

>>>after this i have to refresh client's page in order to show him number
>>
> of
> 
>>>downloaded already news.
>>>So, in session i can store PID of my
>>>/usr/local/apache/htdocs/perl/getting_news.pl and i can check the state
>>
> of
> 
>>>it with
>>>kill 0, $CHILDPID
>>>
>>>But some times it doesn't work. Process of getting news may be finished
>>>suddenly (when still there are undownloaded news in the group) or may do
>>
> not
> 
>>>start even. I don't know why.
>>
>>I suppose that this doesn't work when the child has quit. You can fork a
>>process A, which will fork the real process B that will do the job and A
> 
> will
> 
>>waitpid on B. Since A does nothing but tracking B, it's probably the most
>>robust way.
> 
> 
> Stas, thank you,
> and what do you think if i will not do fork (since it is not so good under mod_perl), but try:
> 
> 1. Do redirect user to another page from Apache's child.
> 2. Remember PID of this Apache's child in DataBase.
> 3. Invoke job by exec() directly in this child (is it possible to send
> answer to client and invoke exec() after this in the same child? i mean the
> client should not be wait finish of exec()).

I don't think so. You could use the cleanup phase, but I believe that Apache 
won't like the control being taken away from it. In any case exec() never 
returns, so you lose a process without Apache knowing about it. Apache still 
thinks that it has this process in its scoreboard accounting. This is probably 
not what you want.

> 4. From redirected (in 1.) page (in any children, it doesn't matter) i will
> check the state of job with PID from the DataBase
> 
> I think it should work, what do you think?

How long is your job? If it's very long it may be more practical to run a 
daemon which will execute the jobs, and the mod_perl process will submit them 
to that daemon. Your generated response then can include a link that will 
cause a query on the daemon to check whether the job is complete. Some people 
use crontab instead of a real daemon.

If the job is not very long (so that user is willing to wait for it to 
finish), having the mod_perl process spawn a son who will spawn a grandson 
will make a more robust solution. I'm talking about the end of the section:
http://perl.apache.org/docs/1.0/guide/performance.html#toc_Avoiding_Zombie_Processes
where you can see an example of a grandkid...

In other words what I propose is that you keep your current kill() usage, but 
use a double fork and immediately free the parent process.

__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com