perl-modperl mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Clinton Gormley <cl...@traveljury.com>
Subject Re: DESTROY not being called on stop/restart
Date Wed, 16 Sep 2009 09:21:40 GMT
On Tue, 2009-09-15 at 14:29 -0500, David Nicol wrote:
> I'm ignorant of internals specifics, but perl's full cleanup on exit
> needs to be called, and is called at an orderly shutdown. It doesn't
> get called at POSIX::exit, or when the process in which the
> interpreter is embedded exits without calling it.
> 
> Presumably apache offers a hook for orderly shutdown and  mod_perl
> takes advantage of that hook to run an orderly shutdown on the
> embedded interpreter.  There is some danger of hanging on exit though,
> so there could be a good argument against not doing that by default.
> 
> Graceful is supposed to do a stop/restart allowing requests to
> complete and so on, so it is easy to imagine that the hook might get
> run under a graceful but not under a stop, as stop is used to exit
> even when hung.
> 

I'm finding the same problem with a graceful-stop.  It may be the nature
of the code that I'm using, which does the following:

  To do a search:
  ---------------
  - check for the search in the cache
  - if result == $LOCK then go back to previous step
  - if no result
    - store $LOCK in cache
    - lock cache (using lexical object with DESTROY)
    - retrieve data from the DB
    - if data
        - store in cache 
  - lock expires because of scope 
    -> DESTROY
      -> if data loaded and stored to cache, then do nothing
      -> else release lock
  - return data     

I'm testing it by:
------------------
  - locking DB search table with SQL
  - clearing the existing cache
  - start apache
  - make two requests for the same thing
    - first locks cache and tries to do query
    - second sees lock and waits
  - apachectl stop / restart / graceful-stop
  - apachectl start
  - retry one request

This results in the last request hanging because the lock from the first
request still hasn't been cleared.

It may be because the code doesn't run to completion because the SQL
query never receives a response, but I'd still have expected DESTROY to
be called.

The docs for mod_perl 1 imply that DESTROY blocks are called unless
PERL_DESTRUCT_LEVEL is set to -1:
http://perl.apache.org/docs/1.0/guide/troubleshooting.html#_warn__child_process_30388_did_not_exit__sending_another_SIGHUP

This environment variable no longer seems to exist, and maybe behaviour
has changed.

Either way, it is a gotcha that should be documented (by somebody who
understands what actually happens when) (... he says, neatly excluding
himself :)

For the record, the child exit handler is being called on
stop/restart/graceful-stop and so handles this situation neatly.

thanks

Clint


Mime
View raw message