mperham/sidekiq — pull request #761 by mrnugget (2013-03-08 14:14:02+00:00)
Title: Refactor signal handling to use a pipe

After seeing your post on the subject of signal handling with ruby 2.0.0 (http://www.mikeperham.com/2013/02/23/signal-handling-with-ruby/) and discovering the self-pipe trick a couple of weeks ago (https://gist.github.com/mrnugget/4769939) I thought that the polling for received signals could be avoided and replaced by an internal pipe.

So I went ahead and implemented the idea of using a pipe instead of polling for a global array. To quote my commit message:

"This commit removes the need to poll a global array for received signals every
second by introducing an internal pipe(2).

The writing end of the pipe is being used in the block trapping the signals.
Whenever a signal is received, the signal's name gets written to the pipe.

Instead of polling for received signals, the code now uses select(2) to
check whether the internal pipe has been written to and can be read from.
select(2) is blocking until one of the passed file descriptors is ready for
reading/writing or has an exception, which means the code does not need to use
`sleep 1` anymore.

So when a signal is sent to the sidekiq process, the signal name gets written to
the internal pipe, select(2) returns and the process can react according to the
received signal. After handling a signal, select(2) gets called again and blocks
until receiving another signal."

I tested this implementation with ruby 2.0.0-p0, 1.9.3-p327 and jruby-1.7.2 — it works fine with all of them.

What do you think? This doesn't change functionality or add a new feature, but I think it's nicer than the polling and sleeping, using select(2) to solve that.