I have a python program that is running a number of worker processes. Because this has to be handled properly to avoid orphaned processes, I have implemented a signal handler to shutdown all worker processes.
The program starts more or less like this:
- Start process pool (starts X number of workers)
- Register signal handlers (
signal.signal(signal.SIGTERM, my_signal_handler)
). I also add another signal handler forSIGINT
with the same handler. - Start seperate thread polling backend (database) and add the tasks to process pool.
- On main thread, poll process pool for results (there is a result
multiprocessing.Queue
that the individual workers add the results to).
The idea is that the two seperate threads started in 3 and 4 keep the tasks running through the machinery.
If I start this manually and call kill -15 <pid>
or kill -2 <pid>
it correctly shuts everything down, waits for processes to join()
. Reading from the documentation, runit sends a TERM
to the process, followed by CONT
. However, running this under runit, it simply shows the standard ok: down: <my_program>: 1s, normally up
, but the process is still running in the background (even the main process, it is UNTOUCHED).
If I then afterwards go out and manually kill the process, I can see in the log file that it shuts down correctly. What am I doing wrong? It seems that runit ONLY kills the 3-line shell script I created to activate the virtualenv, but leaves the actual python process behind.
Even if I run the "run" script directly, I can either run kill
or Ctrl+C (same as SIGINT
) and it shuts down correctly.