1
0
Fork 0
mirror of https://github.com/mperham/sidekiq.git synced 2022-11-09 13:52:34 -05:00

Refactor signal handling to use a pipe

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.
This commit is contained in:
Thorsten Ball 2013-03-08 14:39:33 +01:00
parent 3f483c30a2
commit dfc7e35b11

View file

@ -1,11 +1,11 @@
$sidekiq_signals = []
$self_read, $self_write = IO.pipe
# Signal handlers should do as little as humanly possible
# and defer all work to a non-trap context. We'll have
# the main thread poll for signals and handle them there.
%w(INT TERM USR1 USR2 TTIN).each do |sig|
trap sig do
$sidekiq_signals << sig
$self_write.puts(sig)
end
end
@ -69,9 +69,9 @@ module Sidekiq
end
launcher.run
while true
handle_signals
sleep 1
while readable_io = IO.select([$self_read])
signal = readable_io.first[0].gets.strip
handle_signal(signal)
end
rescue Interrupt
logger.info 'Shutting down'
@ -82,8 +82,7 @@ module Sidekiq
end
end
def handle_signals
while sig = $sidekiq_signals.shift
def handle_signal(sig)
Sidekiq.logger.debug "Got #{sig} signal"
case sig
when 'INT'
@ -119,7 +118,6 @@ module Sidekiq
end
end
end
end
private