import sys, daemon
self.db = somedb.connect() # connect to a DB
self.blah = 127
with open('blah0.txt', 'w') as f:
# doing lots of things here, modifying self.blah
self.db.close() # properly close the DB (sync to disk, etc.)
with open('blah1.txt', 'w') as f:
daemon = test(pidfile='_.pid')
if 'start' == sys.argv:
elif 'stop' == sys.argv:
daemon.before_stop() # AttributeError: test instance has no attribute 'blah'
AttributeError: test instance has no attribute 'blah'
The Daemon code sends a SIGTERM signal to the daemon process to ask it to stop. If you want that something is run by the daemon process itself, it must be run from a signal handler or from an
atexit.register called method.
daemonize method already installs such a method, just call
beforestop from there:
# this one could be either in a subclass or in a modified base daemeon class def delpid(self): if hasattr(self, 'before_stop'): self.before_stop() os.remove(self.pidfile) # this one should be in subclass def before_stop(self): self.db.close() # properly close the DB (sync to disk, etc.) with open('blah1.txt', 'w') as f: f.write(self.blah)
But that is not enough! The Python Standard Library documentation says about
The functions registered via this module are not called when the program is killed by a signal not handled by Python
As the process is expected to receive a SIGTERM signal, you have to install a handler. As shown in one active state recipe, it is damned simple: just ask the program to stop if it receives the signal:
... from signal import signal, SIGTERM ... atexit.register(self.delpid) signal(SIGTERM, lambda signum, stack_frame: exit(1))