Yesterday we had an issue with the different behaviour of “kill “ and “kill -9 “ and in the process I had to refresh my knowledge of Unix signals, learn how you handle them in Ruby and properly learn Rubys exception hierarchy.
To -9 or not to -9?
The unix kill command is perhaps strangely named as it actually sends signals to processes (see “man signal” for a full list). It defaults to sending SIGTERM to the process and the application writer can decide how to treat it by “trapping” it, allowing for a safe shutdown or debug dumps etc. “kill -9” sends SIGKILL and the signals SIGKILL and SIGSTOP cannot be caught, blocked, or ignored by your programs. I think in the first instance you should just use “kill”, give the app the chance to do the right thing then get -9 on its ass if you need to.
Catching signals in Ruby
Is about the simplest code that will trap the “USR1” signal (which you can send with “kill -USR1 “). The USR1 and USR2 signals are left free for you to use however you wish in your applications.
The following two code snippets are the same except one takes the default and the other catches Exception (ie any exception)
So that still works as before and errors in our “do stuff” loop would get caught.
This fails though. You can see that SIGTERM no longer works and CTRL-C from the terminal does not work also. This is because we are catching the SignalException when we do “rescue Exception”. Kill -9 worked though, as it will kill any application as the signal cannot be caught.
Rubys Exception Heirachy
The full exception heirachy (from the excellent cheat gem) is
I think you should only catch StandardError or its children, possibly some of its siblings and avoid catching Exception as you probably dont want to change how the process deals with signals (you could trap them if you need to)