This is part of The Pile, a partial archive of some open source mailing lists and newsgroups.
To: modperl@apache.org
From: Adriano Nagelschmidt Rodrigues <anr@agestado.com.br>
Subject: Class data & preloading modules
Date: Fri, 23 Nov 2001 15:23:39 -0200
Hi,
I have some modules that use the idiom
package Foo;
use Bar;
{
my $bar = Bar->new(args);
sub bar { return $bar }
}
which works fine until one tries to preload them in startup.pl.
I realized that, by preloading, I was innocently sharing the same DBI
object between Apache children (nothing strange happened during
testing, but I guess it was only a question of time & stress).
I also happen to have Foo subclasses that need the DBI connection to
produce otherwise shareable (read only) class data.
My question is about good programming practice in this case. I guess
I have three options:
(init once per MaxRequestsPerChild)
* initialize the class data externally, from within a method.
* do something like
{
my $bar;
sub bar {
$bar = BAR->new(args) unless $bar; # too ugly? performance loss small?
return $bar;
}
}
(init only once)
* initialize everything in the parent Apache, just make sure to create
new DBI connections in the children.
What do you think?
===
To: modperl@apache.org
From: Chris Winters <chris@cwinters.com>
Subject: Re: Class data & preloading modules
Date: Fri, 23 Nov 2001 13:31:10 -0500
* Adriano Nagelschmidt Rodrigues (anr@agestado.com.br) [011123 12:31]:
> ...
> My question is about good programming practice in this case. I guess
> I have three options:
>
> (init once per MaxRequestsPerChild)
>
> * initialize the class data externally, from within a method.
>
> * do something like
>
> {
> my $bar;
>
> sub bar {
> $bar = BAR->new(args) unless $bar; # too ugly? performance loss small?
> return $bar;
> }
> }
>
> (init only once)
>
> * initialize everything in the parent Apache, just make sure to create
> new DBI connections in the children.
Create a PerlChildInitHandler. It will execute every time a new Apache
child is created. In your startup.pl, do:
Apache->push_handlers( PerlChildInitHandler => \&my_init );
The &my_init routine can do whatever you like.
===
To: modperl@apache.org
From: Adriano Nagelschmidt Rodrigues <anr@agestado.com.br>
Subject: Re: Class data & preloading modules
Date: Fri, 23 Nov 2001 17:06:12 -0200
Chris Winters writes:
> Create a PerlChildInitHandler. It will execute every time a new Apache
> child is created. In your startup.pl, do:
>
> Apache->push_handlers( PerlChildInitHandler => \&my_init );
>
> The &my_init routine can do whatever you like.
Thanks Chris & Stas for the suggestion.
But can I use child init handlers without changing the modules' code?
Right now, they are blissfully ignorant that they work under mod_perl
(in fact, they are supposed to work standalone or in a CGI
environment).
Wouldn't this call for a duplication in the initialization code? Sorry
if I didn't understand correctly, I'm far from being an expert...
===
To: Adriano Nagelschmidt Rodrigues <anr@agestado.com.br>
From: Stas Bekman <stas@stason.org>
Subject: Re: Class data & preloading modules
Date: Sat, 24 Nov 2001 03:17:08 +0800
Adriano Nagelschmidt Rodrigues wrote:
> Chris Winters writes:
>
>>Create a PerlChildInitHandler. It will execute every time a new Apache
>>child is created. In your startup.pl, do:
>>
>> Apache->push_handlers( PerlChildInitHandler => \&my_init );
>>
>>The &my_init routine can do whatever you like.
>>
>
> Thanks Chris & Stas for the suggestion.
>
> But can I use child init handlers without changing the modules' code?
> Right now, they are blissfully ignorant that they work under mod_perl
> (in fact, they are supposed to work standalone or in a CGI
> environment).
this should work transparently. Just load your module in the
childinithandler (e.g. have BEGIN block to create closure) or your
suggested check on whether things were already initialized. just try.
> Wouldn't this call for a duplication in the initialization code? Sorry
> if I didn't understand correctly, I'm far from being an expert...
see above, have a flag to test against.
===
To: "Adriano Nagelschmidt Rodrigues" <anr@agestado.com.br>,
From: "Perrin Harkins" <perrin@elem.com>
Subject: Re: Class data & preloading modules
Date: Tue, 27 Nov 2001 22:51:42 -0500
> * initialize everything in the parent Apache, just make sure to create
> new DBI connections in the children.
That's what I would do. It increases the amount of shared memory.
Disconnect the DBI connection when you're done with it. Apache::DBI
doesn't cache connections during startup, so this shouldn't be a
problem.
===