46 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Ruby
		
	
	
	
			
		
		
	
	
			46 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Ruby
		
	
	
	
| # frozen_string_literal: true
 | |
| 
 | |
| module Gitlab
 | |
|   # 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
 | |
|   module SidekiqSignals
 | |
|     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."
 | |
| 
 | |
|     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
 | |
| 
 | |
|     # 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.
 | |
|     def self.blindly_signal_pgroup!(signal)
 | |
|       old_trap = trap(signal, 'IGNORE')
 | |
|       begin
 | |
|         Process.kill(signal, 0)
 | |
|       ensure
 | |
|         trap(signal, old_trap)
 | |
|       end
 | |
|     end
 | |
|   end
 | |
| end
 |