Hi.
Without being an expert, this is my 2 cent :
Kostas Chatzikokolakis wrote:
Hello,
I'd like to ask what is the intended behaviour of
Apache2::ServerUtil->server->push_handlers(PerlCleanupHandler => ...)
compared to
Apache2::RequestUtil->request->push_handlers(PerlCleanupHandler => ...)
On my Ubuntu 8.10 (mod_perl 2.0.4, apache 2.2.9) cleanup handlers
installed on $s seem to be called after *every* request but handlers
installed on $r are called only *once* after the *current* request.
That sounds like the correct behaviour.
On a
RedHat ES 5 (mod_perl 2.0.2, apache 2.2.3) cleanup handlers on $s look
like they are never called.
That sounds like a bug, but..
[...]
Now correctly invokes PerlCleanupHandlers, even if they are the only
handler type configured for that request [Torsten Foertsch]
He's the real expert, I'm not.
Basically, the way I understand this is :
x->push_handlers(handlerType => ref)
means that you are *adding* a handler (which was not there before) to
"x", at a certain moment in time and under certain circumstances.
That handler will be there (and will be invoked), from the moment you
add it, and as long as "x" exists. When "x" ceases to exist, the
handler will also disappear.
$r (the request) exists only during the handling of this request. So any
handler you add to it will cease to exist after this request terminates,
and will thus have effect only on this request.
$s is "the server", which I interpret as being, in a prefork type
Apache, as one of the Apache children processes.
Initially, the Apache child starts, and your handler is not there (*).
Then, based on some event or condition, you do $s->push_handlers(), and
the handler is there. As long as this child is alive (which depends on
many factors), it will continue to be there, and be involved in any
request processed by this particular child.
But when this child terminates, it also disappears. If a new child is
started, whether your handler is again "pushed" onto it, depends on you.
Since you cannot really predict which child will handle the next
request, and for how many requests a child will remain alive, this might
give rise to the funny-looking behaviour you point out, unless you are
very sure that each time a new child is started, you always push your
handler onto it.
The above is my understanding, and for the prefork-type, where each
child is a process. I am a lot less sure of what happens under a
threaded model.
Also, all of the above is based on the fact that you do a
push_handler(), not systematically, but presumably in function of
certain conditions. ((*)Because otherwise why not just put it into your
basic configuration, and have it be there all the time ?).
I can understand easily why one does that within a request.
But I have more trouble understanding why one would use this at the
server level. It means that, depending on some condition, when a new
child starts, you would or would not add a given handler to it.
What would be such a condition that would make sense ?