You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@perl.apache.org by Stas Bekman <st...@stason.org> on 2005/09/08 01:15:18 UTC

PerlChildInitHandler => s/VOID/RUN_ALL/

At the moment Child(Init|Exit) phases are of type VOID, i.e. any failures 
are ignored, which sucks, since you now can't do any reliable 
initialization in the child init phase (e.g. let's say Apache::DBI's 
child_init phase fails). How about making it RUN_ALL instead? The 
immediate gain is that errors are now logged. I don't see any problems 
with backwards compatibility, besides ChildInit phases needing to return 
OK or DECLINED, but most likely there were all doing so anyway.

The only problem I have is how to prevent from Apache to continue on 
failure. Any ideas?

The patch for the first part is below including a basic test (docs will 
follow if there are no objections to this one).

Index: t/conf/post_config_startup.pl
===================================================================
--- t/conf/post_config_startup.pl	(revision 267234)
+++ t/conf/post_config_startup.pl	(working copy)
@@ -41,8 +41,8 @@

  test_method_obj();

+test_child_init();

-
  ### only subs below this line ###

  sub test_apache_resource {
@@ -144,6 +144,19 @@
      $TestModperl::MethodObj = TestModperl::methodobj->new;
  }

+# test startup loglevel setting (under threaded mpms loglevel can be
+# changed only before threads are started) so here we test whether we
+# can still set it after restart
+sub test_child_init {
+    my $s = Apache2::ServerUtil->server;
+    $s->push_handlers(PerlChildInitHandler => \&child_init);
+}
+
+sub child_init {
+    $TestModperl::ChildInit = "Initialised";
+    return Apache2::Const::OK;
+}
+
  sub ModPerl::Test::add_config {
      my $r = shift;

Index: lib/ModPerl/Code.pm
===================================================================
--- lib/ModPerl/Code.pm	(revision 267234)
+++ lib/ModPerl/Code.pm	(working copy)
@@ -55,7 +55,7 @@
          ret  => 'void',
          args => [{type => 'apr_pool_t', name => 'p'},
                   {type => 'server_rec', name => 's'},
-                 {type => 'dummy', name => 'MP_HOOK_VOID'}],
+                 {type => 'dummy', name => 'MP_HOOK_RUN_ALL'}],
      },
      Files      => {
          ret  => 'int',

--- /dev/null	2005-09-07 13:08:05.178257784 -0700
+++ t/response/TestModperl/child_init.pm	2005-09-07 15:50:48.000000000 -0700
@@ -0,0 +1,28 @@
+package TestModperl::child_init;
+
+# Modperl::child_init tests
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache2::Const -compile => 'OK';
+
+sub handler {
+    my $r = shift;
+
+    plan $r, tests => 1;
+
+    # should get set in child_init() registered by test_child_init, in
+    # post_config_startup.pl
+    ok t_cmp $TestModperl::ChildInit,
+        "Initialised",
+        "checking that child_init was run";
+
+    Apache2::Const::OK;
+}
+
+1;
+__END__


-- 
__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://mailchannels.com

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org
For additional commands, e-mail: dev-help@perl.apache.org


Re: PerlChildInitHandler => s/VOID/RUN_ALL/

Posted by Stas Bekman <st...@stason.org>.
Stas Bekman wrote:
> Stas Bekman wrote:
> [...]
> 
>> The only problem I have is how to prevent from Apache to continue on 
>> failure. Any ideas?
> 
> 
> In fact neither a failure in PostConfig prevents from Apache to normall 
> startup:
> 
> [Mon Sep 12 17:38:21 2005] [error] Can't load Perl file: 
> .../t/conf/post_config_startup.pl for server localhost:8529, exiting...
> [Mon Sep 12 17:38:21 2005] [notice] Apache/2.0.55-dev (Unix) 
> mod_ssl/2.0.55-dev OpenSSL/0.9.7e DAV/2 mod_perl/2.0.2-dev Perl/v5.8.7 
> configured -- resuming normal operations

And it eats the original error message, so you have no clue what was the 
problem.


-- 
__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://mailchannels.com

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org
For additional commands, e-mail: dev-help@perl.apache.org


Re: PerlChildInitHandler => s/VOID/RUN_ALL/

Posted by Stas Bekman <st...@stason.org>.
Stas Bekman wrote:
[...]
> The only problem I have is how to prevent from Apache to continue on 
> failure. Any ideas?

In fact neither a failure in PostConfig prevents from Apache to normall 
startup:

[Mon Sep 12 17:38:21 2005] [error] Can't load Perl file: 
.../t/conf/post_config_startup.pl for server localhost:8529, exiting...
[Mon Sep 12 17:38:21 2005] [notice] Apache/2.0.55-dev (Unix) 
mod_ssl/2.0.55-dev OpenSSL/0.9.7e DAV/2 mod_perl/2.0.2-dev Perl/v5.8.7 
configured -- resuming normal operations

-- 
__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://mailchannels.com

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org
For additional commands, e-mail: dev-help@perl.apache.org


Re: PerlChildInitHandler => s/VOID/RUN_ALL/

Posted by "Philippe M. Chiasson" <go...@ectoplasm.org>.
Stas Bekman wrote:
> Geoffrey Young wrote:
> 
>>> It doesn't work in Child(Init|Exit) phases. Not only it doesn't exit, it
>>> doesn't even log the error. See the test in my patch. Add die in
>>> child_init() and you will see.
>>
>> ok, that's problematic - anyplace you call die() from perl-land ought to
>> show up in the logs.  the current behavior is bad (tm).
> 
> Right.
> 
>> but if by exit you mean stop server startup, are you sure that's possible
>> within the confines of httpd?  in prefork you might get no children ever
>> available to receive requests, but I'm not sure that you could make
>> apachectl return an error.  are you?
> 
> That's why I ask. But not exiting is not an option. Not everybody checks
> error_log for problems, and some people have too much noise in those
> files to see something useful.
> 
>>> The fact that httpd ignores the child_init() return value is a problem
>>> that needs to be fixed.
>>
>> ok.  and we can theoretically not ignore it in mod_perl-land.  but
>> what do
>> we do from it?  we can issue croaks all day, but can we make httpd
>> startup
>> stop within the child_init() callback currently?
> 
> I know, hence the question. I suppose the only option is to fix httpd.
> 
> Why httpd aborts on errors during the config, open_logs or post_config
> phase, but not child_init? It sounds like an emission to me, since
> child_init is very similar to any of preceeding to it phases.

Except child_init() is being run _in_ the newly started child, ain't it ?
At that point, aborting is not possible anymore without a mechanism to
notify the parent.

>>>>> The only problem I have is how to prevent from Apache to continue on
>>>>> failure. Any ideas?
>>>> I'm not sure that it makes sense to halt apache on failure in these
>>>> phases.
>>>> you want to shut httpd down if a PerlChildExitHandler fails?  these
>>>> aren't
>>>> part of startup processing so I don't see how they could prevent
>>>> apache from
>>>> starting.
>>>
>>> While I somewhat agree about ChildExit, but not about ChildInit. I'm not
>>> talking hypotethically. I want to use ChildInit for efficiency reasons,
>>> and sometimes things fail, and I have no way to prevent the server from
>>> happily starting.
>>
>> ok, but that's a httpd issue, not a mod_perl one, right?  

If things fail, trap the failure and use log_error and variants to loudly
complain in the error_log

> It's a mod_perl too, since at the moment die() called don't log their
> error messages in error_log, but are simply ignored. (again see my test).

That's _bad_ for sure, should make it somewhere, not dissapear

>> again, unless
>> httpd gives us a mechanism to halt the startup process it's kinda out
>> of our
>> hands.  unless you're saying httpd has a formal mechanism in place we can
>> use.  if it doesn't I'd say we either need to offer a patch to httpd and
>> make things right going forward, or live with what httpd gives us.
> 
> I suppose the trickiness of this issue is that child_init runs in the
> child process. So in order to prevent the server from starting, it needs
> to somehow signal the problem to the parent problem, which given the
> multitude of MPMs (where I think the child_init is called from) it might
> be not so trivial.

Yeah, and the fact that there is no good API for that. It's the same reason
we have had trouble implementing child_terminate() proprely.

--------------------------------------------------------------------------------
Philippe M. Chiasson m/gozer\@(apache|cpan|ectoplasm)\.org/ GPG KeyID : 88C3A5A5
http://gozer.ectoplasm.org/     F9BF E0C2 480E 7680 1AE5 3631 CB32 A107 88C3A5A5

Re: PerlChildInitHandler => s/VOID/RUN_ALL/

Posted by Stas Bekman <st...@stason.org>.
Geoffrey Young wrote:
>>It doesn't work in Child(Init|Exit) phases. Not only it doesn't exit, it
>>doesn't even log the error. See the test in my patch. Add die in
>>child_init() and you will see.
> 
> 
> ok, that's problematic - anyplace you call die() from perl-land ought to
> show up in the logs.  the current behavior is bad (tm).

Right.

> but if by exit you mean stop server startup, are you sure that's possible
> within the confines of httpd?  in prefork you might get no children ever
> available to receive requests, but I'm not sure that you could make
> apachectl return an error.  are you?

That's why I ask. But not exiting is not an option. Not everybody checks 
error_log for problems, and some people have too much noise in those files 
to see something useful.

>>The fact that httpd ignores the child_init() return value is a problem
>>that needs to be fixed.
> 
> 
> ok.  and we can theoretically not ignore it in mod_perl-land.  but what do
> we do from it?  we can issue croaks all day, but can we make httpd startup
> stop within the child_init() callback currently?

I know, hence the question. I suppose the only option is to fix httpd.

Why httpd aborts on errors during the config, open_logs or post_config 
phase, but not child_init? It sounds like an emission to me, since 
child_init is very similar to any of preceeding to it phases.

>>>>The only problem I have is how to prevent from Apache to continue on
>>>>failure. Any ideas?
>>>
>>>
>>>
>>>I'm not sure that it makes sense to halt apache on failure in these
>>>phases.
>>> you want to shut httpd down if a PerlChildExitHandler fails?  these
>>>aren't
>>>part of startup processing so I don't see how they could prevent
>>>apache from
>>> starting.
>>
>>
>>While I somewhat agree about ChildExit, but not about ChildInit. I'm not
>>talking hypotethically. I want to use ChildInit for efficiency reasons,
>>and sometimes things fail, and I have no way to prevent the server from
>>happily starting.
> 
> 
> ok, but that's a httpd issue, not a mod_perl one, right?  

It's a mod_perl too, since at the moment die() called don't log their 
error messages in error_log, but are simply ignored. (again see my test).

> again, unless
> httpd gives us a mechanism to halt the startup process it's kinda out of our
> hands.  unless you're saying httpd has a formal mechanism in place we can
> use.  if it doesn't I'd say we either need to offer a patch to httpd and
> make things right going forward, or live with what httpd gives us.

I suppose the trickiness of this issue is that child_init runs in the 
child process. So in order to prevent the server from starting, it needs 
to somehow signal the problem to the parent problem, which given the 
multitude of MPMs (where I think the child_init is called from) it might 
be not so trivial.

-- 
__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://mailchannels.com

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org
For additional commands, e-mail: dev-help@perl.apache.org


Re: PerlChildInitHandler => s/VOID/RUN_ALL/

Posted by Geoffrey Young <ge...@modperlcookbook.org>.
> It doesn't work in Child(Init|Exit) phases. Not only it doesn't exit, it
> doesn't even log the error. See the test in my patch. Add die in
> child_init() and you will see.

ok, that's problematic - anyplace you call die() from perl-land ought to
show up in the logs.  the current behavior is bad (tm).

but if by exit you mean stop server startup, are you sure that's possible
within the confines of httpd?  in prefork you might get no children ever
available to receive requests, but I'm not sure that you could make
apachectl return an error.  are you?


> The fact that httpd ignores the child_init() return value is a problem
> that needs to be fixed.

ok.  and we can theoretically not ignore it in mod_perl-land.  but what do
we do from it?  we can issue croaks all day, but can we make httpd startup
stop within the child_init() callback currently?

> 
>>> The only problem I have is how to prevent from Apache to continue on
>>> failure. Any ideas?
>>
>>
>>
>> I'm not sure that it makes sense to halt apache on failure in these
>> phases.
>>  you want to shut httpd down if a PerlChildExitHandler fails?  these
>> aren't
>> part of startup processing so I don't see how they could prevent
>> apache from
>>  starting.
> 
> 
> While I somewhat agree about ChildExit, but not about ChildInit. I'm not
> talking hypotethically. I want to use ChildInit for efficiency reasons,
> and sometimes things fail, and I have no way to prevent the server from
> happily starting.

ok, but that's a httpd issue, not a mod_perl one, right?  again, unless
httpd gives us a mechanism to halt the startup process it's kinda out of our
hands.  unless you're saying httpd has a formal mechanism in place we can
use.  if it doesn't I'd say we either need to offer a patch to httpd and
make things right going forward, or live with what httpd gives us.

--Geoff

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org
For additional commands, e-mail: dev-help@perl.apache.org


Re: PerlChildInitHandler => s/VOID/RUN_ALL/

Posted by Stas Bekman <st...@stason.org>.
Geoffrey Young wrote:
> 
> Stas Bekman wrote:
> 
>>At the moment Child(Init|Exit) phases are of type VOID, i.e. any
>>failures are ignored, which sucks, since you now can't do any reliable
>>initialization in the child init phase (e.g. let's say Apache::DBI's
>>child_init phase fails). 
> 
> 
> a call to die() shouldn't be ignored.  that's the typical way to exit from
> void phases.

It doesn't work in Child(Init|Exit) phases. Not only it doesn't exit, it 
doesn't even log the error. See the test in my patch. Add die in 
child_init() and you will see.

It does work in filters.

>>How about making it RUN_ALL instead? The
>>immediate gain is that errors are now logged. I don't see any problems
>>with backwards compatibility, besides ChildInit phases needing to return
>>OK or DECLINED, but most likely there were all doing so anyway.
> 
> 
> what's the rationale for making this phase RUN_ALL but leaving the other
> VOID phases as is?  if die() works then there is an exit strategy for the
> VOID phases.  if die() isn't logged, that's something we ought to fix, not
> necessarily by changing the runtime prototype to RUN_ALL, though.

see above

> also, I'm in favor of keeping these phases programmatically aligned with httpd.

The fact that httpd ignores the child_init() return value is a problem 
that needs to be fixed.

>>The only problem I have is how to prevent from Apache to continue on
>>failure. Any ideas?
> 
> 
> I'm not sure that it makes sense to halt apache on failure in these phases.
>  you want to shut httpd down if a PerlChildExitHandler fails?  these aren't
> part of startup processing so I don't see how they could prevent apache from
>  starting.

While I somewhat agree about ChildExit, but not about ChildInit. I'm not 
talking hypotethically. I want to use ChildInit for efficiency reasons, 
and sometimes things fail, and I have no way to prevent the server from 
happily starting.

The ChildExit is a whole different story, since httpd will kill the server 
w/o letting it complete its cleanup handlers, which I've reported like 4 
years ago, but nobody wants to deal with that. The fact is, you can't do 
any reliable process shutdown cleanups in Apache/mod_perl at the moment. 
But let's not get offtopic on the other issue.

-- 
__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://mailchannels.com

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org
For additional commands, e-mail: dev-help@perl.apache.org


Re: PerlChildInitHandler => s/VOID/RUN_ALL/

Posted by Geoffrey Young <ge...@modperlcookbook.org>.

Stas Bekman wrote:
> At the moment Child(Init|Exit) phases are of type VOID, i.e. any
> failures are ignored, which sucks, since you now can't do any reliable
> initialization in the child init phase (e.g. let's say Apache::DBI's
> child_init phase fails). 

a call to die() shouldn't be ignored.  that's the typical way to exit from
void phases.


> How about making it RUN_ALL instead? The
> immediate gain is that errors are now logged. I don't see any problems
> with backwards compatibility, besides ChildInit phases needing to return
> OK or DECLINED, but most likely there were all doing so anyway.

what's the rationale for making this phase RUN_ALL but leaving the other
VOID phases as is?  if die() works then there is an exit strategy for the
VOID phases.  if die() isn't logged, that's something we ought to fix, not
necessarily by changing the runtime prototype to RUN_ALL, though.

also, I'm in favor of keeping these phases programmatically aligned with httpd.

> 
> The only problem I have is how to prevent from Apache to continue on
> failure. Any ideas?

I'm not sure that it makes sense to halt apache on failure in these phases.
 you want to shut httpd down if a PerlChildExitHandler fails?  these aren't
part of startup processing so I don't see how they could prevent apache from
 starting.

--Geoff

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org
For additional commands, e-mail: dev-help@perl.apache.org