[Python-Dev] Proposal: standard way of defining and executing "atexit" functions...
Peter Funk
pf@artcom-gmbh.de
Tue, 20 Jun 2000 09:32:33 +0200 (MEST)
Hi Skip, Hi David,
David Ascher:
> > If someone fails to use the defined protocol, screw 'em... ;-)
>
> That's unreasonable given that existing tools might include a library which
> might be upgraded to use the new mechanism while the old code used its own
> mechanism happily. For example, I've used my own protocols in the past
> which went something like...
>
> def register_exitfunc(func):
> old_exitfunc = getattr(sys, 'exitfunc', None)
> def wrapper(old_exitfunc=old_exitfunc, new_func=func):
> if old_exitfunc is not None: old_exitfunc()
> new_func()
> sys.exitfunc = wrapper
>
> or some such, creating a call chain instead of a sequence of calls, and it's
> a 'fine' protocol in that it worked fine in the absence of a standard. No
> need to break code if we can avoid it.
Davids wrapper function implements a FIFO strategy for termination.
I think this is not desired. Normally you want LIFO, because higher level
services in an application are initialized later during startup. Those
services usually depend on lower level services, which should still be
available at termination time of the higher level services.
I try to explain this by an example:
Module A provides some kind of network connections.
Module B uses (imports) Module A to access a remote resource administration
server to provide access to remote devices or resources.
During program termination Module B likes to release all resources reserved
for (owned by) the program. It uses Module A to submit a cleanup request to
the server. Module A however wants to close all open network connections.
The following function (termination protocol) solves this by exchanging the
sequence of calls within the wrapper:
def register_exit_func(func, *args, **kw):
import sys
previous_func = sys.exit_func
def wrapped_func(previous_func=previous_func, func=func, args=args, kw=kw):
try:
apply(func, args, kw)
finally:
if previous_func is not None:
previous_func()
sys.exit_func = wrapped_func
In the past I've placed such a function into a common base module of my apps.
But I think, Skip is right, that a termination protocol should be part of
the standard library.
But a separate module 'exit.py' seems to be overkill for single basic
function. May be it should be put into the module 'os'? Handling of
program termination is something, which considered as a generic
operating system service. From the users point of view 'sys' would
be a better place, but this would require rewriting in C: ugly.
I also agree with Skip, that the possibility to unregister an exit_func is
normally not needed. The same effect can be achieved by doing nothing in
the exit_func.
Regards, Peter
--
Peter Funk, Oldenburger Str.86, D-27777 Ganderkesee, Germany, Fax:+49 4222950260
office: +49 421 20419-0 (ArtCom GmbH, Grazer Str.8, D-28359 Bremen)