Module: Gitlab::SidekiqSignals
- Defined in:
- lib/gitlab/sidekiq_signals.rb
Overview
As a process group leader, we can ensure that children of sidekiq are killed at the same time as sidekiq itself, to stop long-lived children from being reparented to init and “escaping”. To do this, we override the default handlers used by sidekiq for INT and TERM signals
Constant Summary collapse
- REPLACE_SIGNALS =
%w[INT TERM].freeze
- SIDEKIQ_CHANGED_MESSAGE =
"Intercepting signal handlers: #{REPLACE_SIGNALS.join(", ")} failed. " \ "Sidekiq should have registered them, but appears not to have done so."
Class Method Summary collapse
-
.blindly_signal_pgroup!(signal) ⇒ Object
The process group leader can forward INT and TERM signals to the whole group.
- .install!(sidekiq_handlers) ⇒ Object
Class Method Details
.blindly_signal_pgroup!(signal) ⇒ Object
The process group leader can forward INT and TERM signals to the whole group. However, the forwarded signal is also received by the leader, which could lead to an infinite loop. We can avoid this by temporarily ignoring the forwarded signal. This may cause us to miss some repeated signals from outside the process group, but that isn’t fatal.
36 37 38 39 40 41 42 43 |
# File 'lib/gitlab/sidekiq_signals.rb', line 36 def self.blindly_signal_pgroup!(signal) old_trap = trap(signal, 'IGNORE') begin Process.kill(signal, 0) ensure trap(signal, old_trap) end end |
.install!(sidekiq_handlers) ⇒ Object
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/gitlab/sidekiq_signals.rb', line 15 def self.install!(sidekiq_handlers) # This only works if we're process group leader return unless Process.getpgrp == Process.pid raise SIDEKIQ_CHANGED_MESSAGE unless REPLACE_SIGNALS == sidekiq_handlers.keys & REPLACE_SIGNALS REPLACE_SIGNALS.each do |signal| old_handler = sidekiq_handlers[signal] sidekiq_handlers[signal] = ->(cli) do blindly_signal_pgroup!(signal) old_handler.call(cli) end end end |