Help -- how to fork an Apache process in mod_perl safely? Not Apache2:Subprocess...

Help -- how to fork an Apache process in mod_perl safely? Not Apache2:Subprocess...

am 25.08.2009 14:11:40 von Victor Danilchenko

Hi all,

I need to be able to fork an Apache process in daemon form, to do some
housekeeping which might potentially take a few seconds. However, when I
do that, I start getting SQL errors (of the "connection lost" type) in
the browser. I do the fairly standard cleanup to daemonize the child
process, but of course it needs to retain the SQL socket open. Here is
my forking code:

sub modperl_kamikaze_fork () {
# You will have to do CORE::exit(0) at the end of the execution.

$SIG{CHLD} = 'IGNORE';
get_m->flush_buffer;
defined (my $kid = fork) or die "Cannot fork: $!\n";
return $kid if $kid;

my $r = get_r;
close STDIN; open STDIN, '/dev/null'
or die "Can't read /dev/null: $!";
close STDOUT; open STDOUT, '>/dev/null'
or die "Can't write to /dev/null: $!";
close STDERR; open STDERR, '>>/tmp/form.log'
or die "Cannot open /tmp/fork.log\n";
setsid
or die "Can't start a new session: $!";

my $oldfh = select STDERR;
local $| = 1;
select $oldfh;
warn "Child (PID $$) spawned.\n";

$r->child_terminate;
}


The Apache2:Subprocess doesn't help me, because I need not to spawn an
external process, but to finish processing in mod_perl context -- just
without bugging the user with it.

Any ideas on how to either fork better, or how to solve this without
forking (e.g. is there a way to 'append' a function call to the request
after the rest of the request is completed)?

Many thanks in advance.

--
Victor Danilchenko
Senior Software Engineer, AskOnline.net
victor@askonline.net - 617-273-0119

Re: Help -- how to fork an Apache process in mod_perl safely? Not

am 25.08.2009 14:16:32 von Perrin Harkins

On Tue, Aug 25, 2009 at 8:11 AM, Victor Danilchenko w=
rote:
> =A0 =A0 =A0 =A0I need to be able to fork an Apache process in daemon form=
, to do
> some housekeeping which might potentially take a few seconds. However, wh=
en
> I do that, I start getting SQL errors (of the "connection lost" type) in =
the
> browser. I do the fairly standard cleanup to daemonize the child process,
> but of course it needs to retain the SQL socket open.

You can't fork and keep using a database connection. You have to open
a new connection in the forked process.

> =A0 =A0 =A0 =A0The Apache2:Subprocess doesn't help me, because I need not=
to spawn
> an external process, but to finish processing in mod_perl context -- just
> without bugging the user with it.

In that case, just use a cleanup handler instead.

- Perrin

Re: Help -- how to fork an Apache process in mod_perl safely? Not

am 25.08.2009 17:04:20 von Igor Chudov

--00032555ae56326dd90471f8a6ec
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

my solution is here:

sub fork_temporary_child {
my $result = fork();
unless( $result ) {
# Do not use SQL in child
dbh->{InactiveDestroy} = 1;
disconnect_dbh;
}
return $result;
}



On Tue, Aug 25, 2009 at 7:11 AM, Victor Danilchenko wrote:

> Hi all,
>
> I need to be able to fork an Apache process in daemon form, to do
> some housekeeping which might potentially take a few seconds. However, when
> I do that, I start getting SQL errors (of the "connection lost" type) in the
> browser. I do the fairly standard cleanup to daemonize the child process,
> but of course it needs to retain the SQL socket open. Here is my forking
> code:
>
> sub modperl_kamikaze_fork () {
> # You will have to do CORE::exit(0) at the end of the execution.
>
> $SIG{CHLD} = 'IGNORE';
> get_m->flush_buffer;
> defined (my $kid = fork) or die "Cannot fork: $!\n";
> return $kid if $kid;
>
> my $r = get_r;
> close STDIN; open STDIN, '/dev/null'
> or die "Can't read /dev/null: $!";
> close STDOUT; open STDOUT, '>/dev/null'
> or die "Can't write to /dev/null: $!";
> close STDERR; open STDERR, '>>/tmp/form.log'
> or die "Cannot open /tmp/fork.log\n";
> setsid
> or die "Can't start a new session: $!";
>
> my $oldfh = select STDERR;
> local $| = 1;
> select $oldfh;
> warn "Child (PID $$) spawned.\n";
>
> $r->child_terminate;
> }
>
>
> The Apache2:Subprocess doesn't help me, because I need not to spawn
> an external process, but to finish processing in mod_perl context -- just
> without bugging the user with it.
>
> Any ideas on how to either fork better, or how to solve this without
> forking (e.g. is there a way to 'append' a function call to the request
> after the rest of the request is completed)?
>
> Many thanks in advance.
>
> --
> Victor Danilchenko
> Senior Software Engineer, AskOnline.net
> victor@askonline.net - 617-273-0119
>

--00032555ae56326dd90471f8a6ec
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

my solution is here:

sub fork_temporary_child {
=A0 my $result =
=3D fork();
=A0 unless( $result ) {
  =A0 # Do not use SQL in c=
hild
  =A0 dbh->{InactiveDestroy} =3D 1;
  =A0 disconnec=
t_dbh;
=A0 }
=A0 return $result;

}
=A0


On Tue, Aug 25, 2009 at 7:1=
1 AM, Victor Danilchenko < online.net">victor@askonline.net> wrote:
=3D"gmail_quote" style=3D"border-left: 1px solid rgb(204, 204, 204); margin=
: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
=A0 =A0 =A0 =A0Hi all,



=A0 =A0 =A0 =A0I need to be able to fork an Apache process in daemon form,=
to do some housekeeping which might potentially take a few seconds. Howeve=
r, when I do that, I start getting SQL errors (of the "connection lost=
" type) in the browser. I do the fairly standard cleanup to daemonize =
the child process, but of course it needs to retain the SQL socket open. He=
re is my forking code:




sub modperl_kamikaze_fork () {

=A0 =A0# You will have to do CORE::exit(0) at the end of the execution. >


=A0 =A0$SIG{CHLD} =3D 'IGNORE';

=A0 =A0get_m->flush_buffer;

=A0 =A0defined (my $kid =3D fork) or die "Cannot fork: $!\n"; >
=A0 =A0return $kid if $kid;



=A0 =A0my $r =3D get_r;

=A0 =A0close STDIN; open STDIN, '/dev/null'

=A0 =A0 =A0 =A0or die "Can't read /dev/null: $!";

=A0 =A0close STDOUT; open STDOUT, '>/dev/null'

=A0 =A0 =A0 =A0or die "Can't write to /dev/null: $!";

=A0 =A0close STDERR; open STDERR, '>>/tmp/form.log'

=A0 =A0 =A0 =A0or die "Cannot open /tmp/fork.log\n";

=A0 =A0setsid

=A0 =A0 =A0 =A0or die "Can't start a new session: $!";



=A0 =A0my $oldfh =3D select STDERR;

=A0 =A0local $| =3D 1;

=A0 =A0select $oldfh;

=A0 =A0warn "Child (PID $$) spawned.\n";



=A0 =A0$r->child_terminate;

}





=A0 =A0 =A0 =A0The Apache2:Subprocess doesn't help me, because I need =
not to spawn an external process, but to finish processing in mod_perl cont=
ext -- just without bugging the user with it.



=A0 =A0 =A0 =A0Any ideas on how to either fork better, or how to solve thi=
s without forking (e.g. is there a way to 'append' a function call =
to the request after the rest of the request is completed)?



=A0 =A0 =A0 =A0Many thanks in advance.



--

=A0 =A0 =A0 =A0Victor Danilchenko

=A0 =A0 =A0 =A0Senior Software Engineer, AskOnline.net

=A0 =A0 =A0 =A0v=
ictor@askonline.net
- 617-273-0119




--00032555ae56326dd90471f8a6ec--

Re: Help -- how to fork an Apache process in mod_perl safely? Not

am 25.08.2009 17:20:59 von William T

--000feaf22688b0dc300471f8e103
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

There are all kinds of problems that you'll encounter and have to solve if
you fork. I found it's better to call at(1) to start another seperate
process immediatly. If you need to pass data JSON worked really well for
me.

-wjt

On Aug 25, 2009 5:12 AM, "Victor Danilchenko" wrote:

Hi all,

I need to be able to fork an Apache process in daemon form, to do
some housekeeping which might potentially take a few seconds. However, when
I do that, I start getting SQL errors (of the "connection lost" type) in the
browser. I do the fairly standard cleanup to daemonize the child process,
but of course it needs to retain the SQL socket open. Here is my forking
code:

sub modperl_kamikaze_fork () {
# You will have to do CORE::exit(0) at the end of the execution.

$SIG{CHLD} = 'IGNORE';
get_m->flush_buffer;
defined (my $kid = fork) or die "Cannot fork: $!\n";
return $kid if $kid;

my $r = get_r;
close STDIN; open STDIN, '/dev/null'
or die "Can't read /dev/null: $!";
close STDOUT; open STDOUT, '>/dev/null'
or die "Can't write to /dev/null: $!";
close STDERR; open STDERR, '>>/tmp/form.log'
or die "Cannot open /tmp/fork.log\n";
setsid
or die "Can't start a new session: $!";

my $oldfh = select STDERR;
local $| = 1;
select $oldfh;
warn "Child (PID $$) spawned.\n";

$r->child_terminate;
}


The Apache2:Subprocess doesn't help me, because I need not to spawn
an external process, but to finish processing in mod_perl context -- just
without bugging the user with it.

Any ideas on how to either fork better, or how to solve this without
forking (e.g. is there a way to 'append' a function call to the request
after the rest of the request is completed)?

Many thanks in advance.

--
Victor Danilchenko
Senior Software Engineer, AskOnline.net
victor@askonline.net - 617-273-0119

--000feaf22688b0dc300471f8e103
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

There are all kinds of problems that you'll encounter and have to so=
lve if you fork.=A0 I found it's better to call at(1) to start another =
seperate process immediatly.=A0 If you need to pass data JSON worked really=
well for me.



-wjt


On Aug 25, 2009 5:12 AM, "Victor Danilche=
nko" <victor@askonline.net<=
/a>> wrote:

=A0 =A0 =A0 =A0Hi all,



=A0 =A0 =A0 =A0I need to be able to fork an Apache process in daemon form,=
to do some housekeeping which might potentially take a few seconds. Howeve=
r, when I do that, I start getting SQL errors (of the "connection lost=
" type) in the browser. I do the fairly standard cleanup to daemonize =
the child process, but of course it needs to retain the SQL socket open. He=
re is my forking code:




sub modperl_kamikaze_fork () {

=A0 =A0# You will have to do CORE::exit(0) at the end of the execution. >


=A0 =A0$SIG{CHLD} =3D 'IGNORE';

=A0 =A0get_m->flush_buffer;

=A0 =A0defined (my $kid =3D fork) or die "Cannot fork: $!\n"; >
=A0 =A0return $kid if $kid;



=A0 =A0my $r =3D get_r;

=A0 =A0close STDIN; open STDIN, '/dev/null'

=A0 =A0 =A0 =A0or die "Can't read /dev/null: $!";

=A0 =A0close STDOUT; open STDOUT, '>/dev/null'

=A0 =A0 =A0 =A0or die "Can't write to /dev/null: $!";

=A0 =A0close STDERR; open STDERR, '>>/tmp/form.log'

=A0 =A0 =A0 =A0or die "Cannot open /tmp/fork.log\n";

=A0 =A0setsid

=A0 =A0 =A0 =A0or die "Can't start a new session: $!";



=A0 =A0my $oldfh =3D select STDERR;

=A0 =A0local $| =3D 1;

=A0 =A0select $oldfh;

=A0 =A0warn "Child (PID $$) spawned.\n";



=A0 =A0$r->child_terminate;

}





=A0 =A0 =A0 =A0The Apache2:Subprocess doesn't help me, because I need =
not to spawn an external process, but to finish processing in mod_perl cont=
ext -- just without bugging the user with it.



=A0 =A0 =A0 =A0Any ideas on how to either fork better, or how to solve thi=
s without forking (e.g. is there a way to 'append' a function call =
to the request after the rest of the request is completed)?



=A0 =A0 =A0 =A0Many thanks in advance.



--

=A0 =A0 =A0 =A0Victor Danilchenko

=A0 =A0 =A0 =A0Senior Software Engineer, AskOnline.net

=A0 =A0 =A0 =A0
v=
ictor@askonline.net
- 617-273-0119



--000feaf22688b0dc300471f8e103--

Re: Help -- how to fork an Apache process in mod_perl safely? Not Apache2:Subprocess...

am 13.09.2009 00:11:15 von Victor Danilchenko

William T wrote:
> There are all kinds of problems that you'll encounter and have to solve
> if you fork. I found it's better to call at(1) to start another
> seperate process immediatly. If you need to pass data JSON worked
> really well for me.

Thanks, that's what I ended up doing. First I ended up having to move
the processing into an external script call anyway, and then I tried
Apache2::SubProcess, and it ended up working, but my script was randomly
receiving TERM signals... it's handleable of course, but I decided to go
with the 'at' technique, it's safer that way, I suppose.



>> On Aug 25, 2009 5:12 AM, "Victor Danilchenko" >> > wrote:
>>
>> Hi all,
>>
>> I need to be able to fork an Apache process in daemon form, to
>> do some housekeeping which might potentially take a few seconds.
>> However, when I do that, I start getting SQL errors (of the
>> "connection lost" type) in the browser. I do the fairly standard
>> cleanup to daemonize the child process, but of course it needs to
>> retain the SQL socket open. Here is my forking code:
>>
>> sub modperl_kamikaze_fork () {
>> # You will have to do CORE::exit(0) at the end of the execution.
>>
>> $SIG{CHLD} = 'IGNORE';
>> get_m->flush_buffer;
>> defined (my $kid = fork) or die "Cannot fork: $!\n";
>> return $kid if $kid;
>>
>> my $r = get_r;
>> close STDIN; open STDIN, '/dev/null'
>> or die "Can't read /dev/null: $!";
>> close STDOUT; open STDOUT, '>/dev/null'
>> or die "Can't write to /dev/null: $!";
>> close STDERR; open STDERR, '>>/tmp/form.log'
>> or die "Cannot open /tmp/fork.log\n";
>> setsid
>> or die "Can't start a new session: $!";
>>
>> my $oldfh = select STDERR;
>> local $| = 1;
>> select $oldfh;
>> warn "Child (PID $$) spawned.\n";
>>
>> $r->child_terminate;
>> }
>>
>>
>> The Apache2:Subprocess doesn't help me, because I need not to
>> spawn an external process, but to finish processing in mod_perl
>> context -- just without bugging the user with it.
>>
>> Any ideas on how to either fork better, or how to solve this
>> without forking (e.g. is there a way to 'append' a function call to
>> the request after the rest of the request is completed)?
>>
>> Many thanks in advance.
>>
>> --
>> Victor Danilchenko
>> Senior Software Engineer, AskOnline.net
>> victor@askonline.net - 617-273-0119
>


--
Victor Danilchenko
Senior Software Engineer, AskOnline.net
victor@askonline.net - 617-273-0119