shared variable between PerlChildInitHandler and PerlResponseHandler

--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

<html><head><style type="text/css"><!-- DIV {margin:0px;} --></style></head><body><div style="font-family:garamond,new york,times,serif;font-size:12pt;color:#000000;"><div>Hi, all:<br>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.<br><br>The basic scenario is:<br><br><div style="margin-left: 40px;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">package StartupLog;</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><br style="font-family: Courier New,courier,monaco,monos
pace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;"># the variable I'm testing</span><br style="font-family: Courier
New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">my $sticky = 0;</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">sub child_init {</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">    $sticky = 1;</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">    return 0;</span><br style="font-family: Courier New,cou
rier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">}</span><br style="font-family: Courier
New,courier,monaco,monospace,sans-serif;"><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">sub handler {</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">    warn __PACKAGE__ . " sticky = $sticky\n";    ### always says "0" but should say "1"</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">    return 0;</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,m
onospace,sans-serif;">}</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier
New,courier,monaco,monospace,sans-serif;">1;</span><br></div><br>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. <br><br>Thank you for any help,<br>/m<br></div>
</div></body></html>
--0-171081317-1282201961=:93924--
Mark Risher [ Do, 19 August 2010 09:12 ] [ ID #2046322 ]

Re: shared variable between PerlChildInitHandler and PerlResponseHandler

On Thursday, August 19, 2010 09:12:41 Mark Risher wrote:
> 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 =3D 0;
>
> sub child_init {
> $sticky =3D 1;
> return 0;
> }
>
> sub handler {
> warn __PACKAGE__ . " sticky =3D $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.

The only thing where mod_perl may stay in the way here is if you use someho=
w a
different interpreter for child_init than for handler. Do you use a threade=
d
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"?
Try to print \$sticky in both handlers.
3) perhaps your intend was to use a package variable (the warning you print=

out makes me think so)

Torsten Förtsch

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

Like fantasy? http://kabatinte.net
torsten.foertsch [ Do, 19 August 2010 10:15 ] [ ID #2046323 ]

Re: shared variable between PerlChildInitHandler and PerlResponseHandler

Thank you for the suggestions. Unfortunately, I am still not able to make =
=0Ait work.=0A=0ASpurred by your advice, I examined my apache2.conf config.=
Here it is:=0A=0APerlSwitches -I/mnt/hgfs/src/api # the path where my m=
odules live=0APerlModule StartupLog=0APerlChildInitHandler StartupLog::chil=
d_init=0A<Location /event>=0A SetHandler modperl =0A PerlResponseHa=
ndler StartupLog::handler=0A</Location>=0A=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 =0A=0A> 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?=0A=0A[mr] I haven't changed the MPM, and I'm running on a Li=
nux host. I do not have =0Athe +Parent option=0A=0A=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"? =0A=0A> Try to print \$sticky in both handl=
ers.=0A=0A[mr] I'm getting different addresses, which illustrates the probl=
em=0A=0A2010/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=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.=0A=0A=0A=0A=
Thanks again!=0A/m
Mark Risher [ Do, 19 August 2010 18:24 ] [ ID #2046324 ]

Re: shared variable between PerlChildInitHandler and PerlResponseHandler

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.)
aw [ Do, 19 August 2010 18:42 ] [ ID #2046325 ]

Re: shared variable between PerlChildInitHandler and PerlResponseHandler

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
> >
> > 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?
>
> [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:

<Perl>
package My::XX;

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

my $var;

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

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

sub Response {
my ($r)=3D [at] _;

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

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

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

PerlChildInitHandler My::XX::Init
<Location /My/XX>
SetHandler modperl
PerlResponseHandler My::XX::Response
</Location>

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
I see multiple occurrences of var=3D2? There are multiple apache instances=

active. Each one has its own perl interpreter. So I have several interprete=
rs
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 [at] _;
warn "$$ $prefix: var=3D".(defined $var ? "'$var'" : "UNDEF");
}

Torsten Förtsch

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

Like fantasy? http://kabatinte.net
torsten.foertsch [ Do, 19 August 2010 19:06 ] [ ID #2046326 ]
Webserver » gmane.comp.apache.mod-perl » shared variable between PerlChildInitHandler and PerlResponseHandler

Vorheriges Thema: [ANNOUNCE] Apache-Reload 0.11
Nächstes Thema: FreeBSD error