diff --git a/README.md b/README.md index fda0be4..b4f75e8 100644 --- a/README.md +++ b/README.md @@ -219,6 +219,30 @@ You can then see the notification in action by (re-)starting the service: `syste You can do a lot more via [sd_notify], see its documentation for details. +### Gracefully shutting down on systemd stop + +When systemd stops your service ( using `systemctl stop python_demo_service` ) it sends the signal SIGTERM. You can do the same with `kill -SIGTERM ` for testing. + +If you do not register a handler for SIGTERM your code will be terminated immediately. If you register a handler you can do some last tasks before exiting (e.g. writing and closing a file and showing an exit message). + +```python +import time +import systemd.daemon +import signal +import sys + +def graceful_exit(signal_number,stack_frame): + systemd.daemon.notify('STOPPING=1') + print("Python Demo Service received signal {}. Stopping now.".format(signal.Signals(signal_number).name)) + time.sleep(5) + print("Python Demo Service has shutdown. Bye bye now!") + sys.exit(0) + +# register SIGTERM and SIGINT handlers to enable graceful shutdown of service +signal.signal(signal.SIGINT, graceful_exit) +signal.signal(signal.SIGTERM, graceful_exit) +``` + ## Creating a System Service Once you have a working user service you can turn it into a system service. Remember, however, that system services run in the system's central systemd instance and have a greater potential for disturbing your system's stability or security when not implemented correctly. In many cases, this step isn't really necessary and a user service will do just fine. diff --git a/python_demo_service.py b/python_demo_service.py index 67648fd..e4a73b0 100644 --- a/python_demo_service.py +++ b/python_demo_service.py @@ -3,8 +3,23 @@ if __name__ == '__main__': import time import systemd.daemon + import signal + import sys + + # graceful shutdown routine - gets called when process gets SIGTERM (systemd stop) or SIGINT (keyboard ctrl+c) + def graceful_exit(signal_number,stack_frame): + systemd.daemon.notify('STOPPING=1') + print("Python Demo Service received signal {}. Stopping now.".format(signal.Signals(signal_number).name)) + time.sleep(5) + print("Python Demo Service has shutdown. Bye bye now!") + sys.exit(0) print('Starting up ...') + + # register SIGTERM and SIGINT handlers to enable graceful shutdown of service + signal.signal(signal.SIGINT, graceful_exit) + signal.signal(signal.SIGTERM, graceful_exit) + time.sleep(10) print('Startup complete') # Tell systemd that our service is ready