Forking in postconfig stage

Forking in postconfig stage

am 12.11.2010 11:42:51 von Oliver Frommel

Hi there,

I'd like to know if it's possible to fork an infinite loop in the =
postconfig stage of the Apache lifecycle. I am trying to do it in a file =
that I 'use' in the startup.pl that in turn is called by =
PerlPostConfigRequire. The fork code I am using is almost the same as =
the "Complete fork example" from the book, however I had to remove all =
references to the Apache request $r because it is not available at this =
stage. In the child process I am creating data that is exposed to other =
requests via IPC::Shareable, but the requests just seem to hang.=20

The code looks like this:

startup.pl:
....
use Datastore::Cache ( );
....

Datastore/Cache.pm:
....
if ($kid) {
...
} else {
tie $H, 'IPC::Shareable', 'Test', {create =3D> 1, mode =3D> 0666};

while(1) {
my $rnd =3D rand(5);
$H =3D $rnd;
sleep(60);
}
}


As you can see, the general problem I am trying to solve is the global =
creation of some data that is subject to global change (not dependent on =
requests) but is available to all requests on a specific URL. Maybe =
there better ways of achieving my general goal than forking?

Thanks for your help
Oliver

Re: Forking in postconfig stage

am 12.11.2010 15:38:38 von torsten.foertsch

On Friday, November 12, 2010 11:42:51 Oliver Frommel wrote:
> I'd like to know if it's possible to fork an infinite loop in the
> postconfig stage of the Apache lifecycle. I am trying to do it in a file
> that I 'use' in the startup.pl that in turn is called by
> PerlPostConfigRequire. The fork code I am using is almost the same as the
> "Complete fork example" from the book, however I had to remove all
> references to the Apache request $r because it is not available at this
> stage. In the child process I am creating data that is exposed to other
> requests via IPC::Shareable, but the requests just seem to hang.=20
>=20
> The code looks like this:
>=20
> startup.pl:
> ...
> use Datastore::Cache ( );
> ...
>=20
> Datastore/Cache.pm:
> ...
> if ($kid) {
> ...
> } else {
> tie $H, 'IPC::Shareable', 'Test', {create =3D> 1, mode =3D> 0666};
>=20
> while(1) {
> my $rnd =3D rand(5);
> $H =3D $rnd;
> sleep(60);
> }
> }
>=20
>=20
> As you can see, the general problem I am trying to solve is the global
> creation of some data that is subject to global change (not dependent on
> requests) but is available to all requests on a specific URL. Maybe there
> better ways of achieving my general goal than forking?

The fork is certainly not the problem.


sub My::PostConfig {
use IPC::ScoreBoard;
use Apache2::ServerUtil ();
if( Apache2::ServerUtil::restart_count>=3D2 ) {
$My::sb=3DSB::anon 0, 0, 3;
my $pid;
select undef, undef, undef, 0.1 until defined($pid=3Dfork);
unless($pid) {
SB::set_extra $My::sb, 2, $$; # PID
SB::set_extra $My::sb, 1, 1; # running
while( SB::get_extra $My::sb, 1 ) {
SB::set_extra $My::sb, 0, int rand 0x7fffffff; # value
sleep 1;
}
SB::set_extra $My::sb, 2, 0; # PID
require POSIX;
POSIX::_exit 0;
kill 'KILL', $$; # just in case _exit() fails
}
}
0;
}

sub My::Reponse {
use Apache2::RequestRec ();
use Apache2::RequestIO ();
my ($r)=3D@_;
my @l=3DSB::get_all_extra $My::sb;
SB::set_extra $My::sb, 1, 0 if $r->args eq 'stop';
$r->content_type('text/plain');
$r->print("value=3D$l[0], running=3D$l[1], pid=3D$l[2]\n");
0;
}

PerlPostConfigHandler My::PostConfig

SetHandler modperl
PerlResponseHandler My::Response


$ curl http://localhost/test
value=3D380451520, running=3D1, pid=3D6265
$ curl http://localhost/test
value=3D1301930535, running=3D1, pid=3D6265
$ curl http://localhost/test?stop
value=3D1285288548, running=3D1, pid=3D6265
$ curl http://localhost/test
value=3D1285288548, running=3D0, pid=3D0

I don't have IPC::Shareable here. So I took IPC::ScoreBoard. IPC::ScoreBoar=
d=20
can only store integer values but it does that without locking. Instead it=
=20
uses atomic operations provided by the hardware. That module is quite new. =
So=20
you might expect bugs.

Another module that I use quite extensively is MMapDB. It might be better=20
suited to your task.

Torsten Förtsch

=2D-=20
Need professional modperl support? Hire me! (http://foertsch.name)

Like fantasy? http://kabatinte.net

Re: Forking in postconfig stage

am 15.11.2010 10:06:03 von Oliver Frommel

> The fork is certainly not the problem.
>
> ...

I didn't understand all of your code but got it to work with some
modifications (for instance "POSIX::_exit(0)"), so thanks for your help.

Unfortunately after all my solution was slower than the PHP thing I
wanted to substitute, although I was trying out your IPC::Scoreboard and
IPC::Shareable.

Best
Oliver