Yves said:
I did a few tests with this script:
class byebye:
def __del__(self):
print 'Bye, bye...'
x = byebye()
x.del() gets executed if:
-I del x, then run gc.collect()
-simply exit the script
-get the script to abort on an exception
But if I kill it with the default signal TERM, the script dies, but I
don't get the message, so I am assuming that python isn't taking the
time to cleanup, even though that is (was) what TERM was intended for.
TERM signal is unix specific. There is no special syntax/programming
structure for signals inside the Python language, since it would be
platform dependent. For simple client programs, usually it is not needed
to setup signal handlers because they can easily be controlled in other
ways.
For sensitive resources, instead of writing __del__ methods, you should
create a "close()" method. Python does this with file objects, DB API
2.0 with database connection objects etc. Then you can do
res = create_resource()
try:
use_resource()
finally:
res.close() # Must free resource, but the object can still be alive...
It is more common to use signals when you have more threads or child
processes. You can use something like:
import threading
import signal
stop_requested = threading.Event()
exited_on_sigterm = False
def free_all_resources():
pass # Free your resources here!
def sigterm_handler(signum, frame):
"""Stop the server gracefully when on SIGTERM."""
global stop_requested
global exited_on_sigterm
exited_on_sigterm = True
stop_requested.set()
free_all_resources()
def main():
global stop_requested
global exited_on_sigterm
logger = servicelog.getLogger('main',filename=LOGFILENAME)
logger.info('Setting up the SIGTERM signal handler.')
signal.signal(signal.SIGTERM, sigterm_handler) # Setup signal handler
logger.info('Starting watchdog thread')
watchdog = WatchDog()
watchdog.start()
worker1 = create_worker(stop_requested)
worker2 = create_worker(stop_requested)
# etc. Prepare things here...
try:
try:
server = create_my_server()
server.serve_until_not_stopped()
except Exception, e:
logger.error(dumpexc(e))
raise e
finally:
stop_requested.set() # Ask other threads to stop cooperatively
# Join all threads here
watchdog.join()
worker1.join()
worder2.join()
# etc. wait for all threads to exit cooperatively.
if exited_on_sigterm:
logger.warning('Exited on SIGTERM!')
Best,
Laszlo