I wrote a simple daemon in Python which is based on Gevent. The daemon needs to do some cleanup before it exists, so it is necessary that it can handle the TERM signal, preform its cleanup and exit gracefully. In a single threaded daemon which is not based on Gevent, I used the Python's signal module to set a signal handler for the TERM signal. The signal handler throws an user defined exception which is called TermSignal. The main thread of the daemon can just catch the TermSignal exception, do its cleanup and exit.
This solution did not work as expected when I tried to implement it in a daemon based on Gevent. The daemon has a main greenlet that calls joinall on the workers greenlets. the joinall call is wrapped in try/except block which catches the KeyboardInterrupt, which allows the daemon to preform its cleanup when it runs without daemonizing. However, when I implemented the solution above and sent a TERM signal to the process, I could see in the console window that one of the worker greenlets raised the TermSignal exception instead of the main greenlet. This uncaught exception did not proagate to the main greenlet, despite the face that I called joinall with raise_error parameter set to True. The result was that one of the worker greenlets crashed due to the exception, but the daemon did not exit at all.