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