shared variable between PerlChildInitHandler and PerlResponseHandler

shared variable between PerlChildInitHandler and PerlResponseHandler

am 19.08.2010 09:12:41 von Mark Risher

--0-171081317-1282201961=:93924
Content-Type: text/plain; charset=us-ascii

Hi, all:
I am trying to load a configuration file into a hash during my
PerlChildInitHandler and then access the values from PerlResponseHandler.
However, even though the process number is the same, it seems that variables
changed during the child_init() call revert back to their default values when
handler() gets called.

The basic scenario is:


package StartupLog;

# the variable I'm testing
my $sticky = 0;

sub child_init {
$sticky = 1;
return 0;
}

sub handler {
warn __PACKAGE__ . " sticky = $sticky\n"; ### always says "0" but should
say "1"
return 0;
}
1;

I've been tearing my hair out for hours on this one. Is this something intrinsic
to mod_perl that I'm overlooking? I can't find any good examples of loading a
config during the PerlChildInit, even though that seems like the best time for
me to load it.


Thank you for any help,
/m

--0-171081317-1282201961=:93924
Content-Type: text/html; charset=us-ascii

Hi, all:
I am trying to load a configuration file into a hash during my PerlChildInitHandler and then access the values from PerlResponseHandler. However, even though the process number is the same, it seems that variables changed during the child_init() call revert back to their default values when handler() gets called.

The basic scenario is:

package StartupLog;

# the variable I'm testing
my $sticky = 0;

sub child_init {
    $sticky = 1;
    return 0;
}

sub handler {
    warn __PACKAGE__ . " sticky = $sticky\n";    ### always says "0" but should say "1"
    return 0;
}
1;

I've been tearing my hair out for hours on this one. Is this something intrinsic to mod_perl that I'm overlooking? I can't find any good examples of loading a config during the PerlChildInit, even though that seems like the best time for me to load it.

Thank you for any help,
/m


--0-171081317-1282201961=:93924--

Re: shared variable between PerlChildInitHandler and PerlResponseHandler

am 19.08.2010 10:15:41 von torsten.foertsch

On Thursday, August 19, 2010 09:12:41 Mark Risher wrote:
> I am trying to load a configuration file into a hash during my=20
> PerlChildInitHandler and then access the values from PerlResponseHandler.=
=20
> However, even though the process number is the same, it seems that
> variables changed during the child_init() call revert back to their
> default values when handler() gets called.
>=20
> The basic scenario is:
>=20
>=20
> package StartupLog;
>=20
> # the variable I'm testing
> my $sticky =3D 0;
>=20
> sub child_init {
> $sticky =3D 1;
> return 0;
> }
>=20
> sub handler {
> warn __PACKAGE__ . " sticky =3D $sticky\n"; ### always says "0" but
> should say "1"
> return 0;
> }
> 1;
>=20
> I've been tearing my hair out for hours on this one. Is this something
> intrinsic to mod_perl that I'm overlooking? I can't find any good
> examples of loading a config during the PerlChildInit, even though that
> seems like the best time for me to load it.

The only thing where mod_perl may stay in the way here is if you use someho=
w a=20
different interpreter for child_init than for handler. Do you use a threade=
d=20
MPM, e.g. windows? Do you use the +Parent PerlOption in a VHost?

Otherwise, the bug is somewhere in your code. Try to answer a few questions:

1) is the child_init handler called?
2) are handler, child_init and $sticky in the same scope? Forgot "use stric=
t"?=20
Try to print \$sticky in both handlers.
3) perhaps your intend was to use a package variable (the warning you print=
=20
out makes me think so)

Torsten Förtsch

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

Like fantasy? http://kabatinte.net

Re: shared variable between PerlChildInitHandler and PerlResponseHandler

am 19.08.2010 18:24:15 von Mark Risher

Thank you for the suggestions. Unfortunately, I am still not able to make =
=0Ait work. Spurred by your advice, I examined my apache2.conf config.=
Here it is: PerlSwitches -I/mnt/hgfs/src/api # the path where my m=
odules live=0APerlModule StartupLog=0APerlChildInitHandler StartupLog::chil=
d_init=0A=0A SetHandler modperl =0A PerlResponseHa=
ndler StartupLog::handler=0A
=0AIn answer to your questions=
:=0A> The only thing where mod_perl may stay in the way here is if you use =
somehow a > different interpreter for child_init than for handler. Do=
you use a threaded =0A> MPM, e.g. windows? Do you use the +Parent PerlOpti=
on in a VHost? [mr] I haven't changed the MPM, and I'm running on a Li=
nux host. I do not have =0Athe +Parent option =0A> Otherwise, the bug =
is somewhere in your code. Try to answer a few questions:=0A> 1) is the chi=
ld_init handler called?=0A> 2) are handler, child_init and $sticky in the s=
ame scope? Forgot "use strict"? > Try to print \$sticky in both handl=
ers. [mr] I'm getting different addresses, which illustrates the probl=
em 2010/08/19 18:13:37 child_init &sticky =3D SCALAR(0x220ea748)=0A201=
0/08/19 18:13:37 child_init sticky (pre) =3D 0=0A2010/08/19 18:13:37 child_=
init sticky (post) =3D 1=0A...=0A2010/08/19 18:13:48 handler sticky (should=
be 1)=3D 0=0A2010/08/19 18:13:48 handler &sticky =3D SCALAR(0x23102e28)=0A=
=0A> 3) perhaps your intend was to use a package variable (the warni=
ng you print =0A> out makes me think so)=0A[mr] I've gone back and forth on=
using a package variable; the warn statement =0Awas a remnant. =
Thanks again!=0A/m

Re: shared variable between PerlChildInitHandler and PerlResponseHandler

am 19.08.2010 18:42:33 von aw

Mark Risher wrote:
....
>
> [mr] I'm getting different addresses, which illustrates the problem
>
> 2010/08/19 18:13:37 child_init &sticky = SCALAR(0x220ea748)
> 2010/08/19 18:13:37 child_init sticky (pre) = 0
> 2010/08/19 18:13:37 child_init sticky (post) = 1
> ...
> 2010/08/19 18:13:48 handler sticky (should be 1)= 0
> 2010/08/19 18:13:48 handler &sticky = SCALAR(0x23102e28)
>
Have you tried :

package StartupLog;

use strict;

# the variable I'm testing
our $sticky = 0;

....
(I don't think that the "= 0" bit is ever going to be executed, but your are doing it
anyway in your init handler.)

Re: shared variable between PerlChildInitHandler and PerlResponseHandler

am 19.08.2010 19:06:38 von torsten.foertsch

On Thursday, August 19, 2010 18:24:15 Mark Risher wrote:
> > The only thing where mod_perl may stay in the way here is if you use
> > somehow a=20
> >=20
> > different interpreter for child_init than for handler. Do you use a
> > threaded MPM, e.g. windows? Do you use the +Parent PerlOption in a
> > VHost?
>=20
> [mr] I haven't changed the MPM, and I'm running on a Linux host. I do not
> have the +Parent option

httpd -V ?

could you post the httpd.conf?

could you post the complete code (as simplified as possible)?

As an example I have just added the following lines to my httpd.conf:


package My::XX;

use strict;
use Apache2::RequestRec ();
use Apache2::RequestIO ();

my $var;

sub pv {
my ($prefix)=3D@_;
warn "$prefix: var=3D".(defined $var ? "'$var'" : "UNDEF");
}

sub Init {
pv 'Init before';
$var++;
pv 'Init after';
0;
}

sub Response {
my ($r)=3D@_;

$r->content_type('text/plain');

pv 'Response before';
$var++;
pv 'Response after';

$r->print("$var\n");
0;
}


PerlChildInitHandler My::XX::Init

SetHandler modperl
PerlResponseHandler My::XX::Response


After a restart I see these lines in the error_log:

Init before: var=3DUNDEF at /etc/opt/apache-prefork/httpd.conf line 442.
Init after: var=3D'1' at /etc/opt/apache-prefork/httpd.conf line 442.
Init before: var=3DUNDEF at /etc/opt/apache-prefork/httpd.conf line 442.
Init after: var=3D'1' at /etc/opt/apache-prefork/httpd.conf line 442.
Init before: var=3DUNDEF at /etc/opt/apache-prefork/httpd.conf line 442.
Init after: var=3D'1' at /etc/opt/apache-prefork/httpd.conf line 442.
Init before: var=3DUNDEF at /etc/opt/apache-prefork/httpd.conf line 442.
Init after: var=3D'1' at /etc/opt/apache-prefork/httpd.conf line 442.
Init before: var=3DUNDEF at /etc/opt/apache-prefork/httpd.conf line 442.
Init after: var=3D'1' at /etc/opt/apache-prefork/httpd.conf line 442.

and each "curl http://localhost/My/XX" produces a pair of these:

Response before: var=3D'1' at /etc/opt/apache-prefork/httpd.conf line 442.
Response after: var=3D'2' at /etc/opt/apache-prefork/httpd.conf line 442.
Response before: var=3D'1' at /etc/opt/apache-prefork/httpd.conf line 442.
Init before: var=3DUNDEF at /etc/opt/apache-prefork/httpd.conf line 442.
Response after: var=3D'2' at /etc/opt/apache-prefork/httpd.conf line 442.
Init after: var=3D'1' at /etc/opt/apache-prefork/httpd.conf line 442.
Response before: var=3D'1' at /etc/opt/apache-prefork/httpd.conf line 442.
Response after: var=3D'2' at /etc/opt/apache-prefork/httpd.conf line 442.
Response before: var=3D'1' at /etc/opt/apache-prefork/httpd.conf line 442.
Response after: var=3D'2' at /etc/opt/apache-prefork/httpd.conf line 442.
Response before: var=3D'1' at /etc/opt/apache-prefork/httpd.conf line 442.
Response after: var=3D'2' at /etc/opt/apache-prefork/httpd.conf line 442.
Response before: var=3D'2' at /etc/opt/apache-prefork/httpd.conf line 442.
Response after: var=3D'3' at /etc/opt/apache-prefork/httpd.conf line 442.
Response before: var=3D'1' at /etc/opt/apache-prefork/httpd.conf line 442.
Response after: var=3D'2' at /etc/opt/apache-prefork/httpd.conf line 442.
Response before: var=3D'2' at /etc/opt/apache-prefork/httpd.conf line 442.
Response after: var=3D'3' at /etc/opt/apache-prefork/httpd.conf line 442.
Response before: var=3D'2' at /etc/opt/apache-prefork/httpd.conf line 442.
Response after: var=3D'3' at /etc/opt/apache-prefork/httpd.conf line 442.

You see $var gets incremented and it preserves its state between calls. Why=
do=20
I see multiple occurrences of var=3D2? There are multiple apache instances=
=20
active. Each one has its own perl interpreter. So I have several interprete=
rs=20
and hence several $var instances that are incremented independently.

Modify pv() to print out the process ID and you can see it:

sub pv {
my ($prefix)=3D@_;
warn "$$ $prefix: var=3D".(defined $var ? "'$var'" : "UNDEF");
}

Torsten Förtsch

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

Like fantasy? http://kabatinte.net