Class: ServiceSkeleton::SignalManager
- Inherits:
-
Object
- Object
- ServiceSkeleton::SignalManager
- Includes:
- LoggingHelpers
- Defined in:
- lib/service_skeleton/signal_manager.rb
Overview
Manage signals in a sane and safe manner.
Signal handling is a shit of a thing. The code that runs when a signal is triggered can't use mutexes (which are used in all sorts of places you might not expect, like Logger!) or anything else that might block. This greatly constrains what you can do inside a signal handler, so the standard approach is to stuff a character down a pipe, and then have the real signal handling run later.
Also, there's always the (slim) possibility that something else might have hooked into a signal we want to receive. Because only a single signal handler can be active for a given signal at a time, we need to "chain" the existing handler, by calling the previous signal handler from our signal handler after we've done what we need to do. This class takes care of that, too, because it's a legend.
So that's what this class does: it allows you to specify signals and associated blocks of code to run, it sets up signal handlers which send notifications to a background thread and chain correctly, and it manages the background thread to receive the notifications and execute the associated blocks of code outside of the context of the signal handler.
Instance Method Summary collapse
-
#initialize(logger:, counter:, signals:) ⇒ SignalManager
constructor
Setup a signal handler instance.
- #run ⇒ Object
- #shutdown ⇒ Object
Constructor Details
#initialize(logger:, counter:, signals:) ⇒ SignalManager
Setup a signal handler instance.
36 37 38 39 40 41 42 43 44 |
# File 'lib/service_skeleton/signal_manager.rb', line 36 def initialize(logger:, counter:, signals:) @logger, @signal_counter, @signal_list = logger, counter, signals @registry = Hash.new { |h, k| h[k] = SignalHandler.new(k) } @signal_list.each do |sig, proc| @registry[signum(sig)] << proc end end |
Instance Method Details
#run ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/service_skeleton/signal_manager.rb', line 46 def run logger.info(logloc) { "Starting signal manager for #{@signal_list.length} signals" } @r, @w = IO.pipe install_signal_handlers signals_loop ensure remove_signal_handlers end |
#shutdown ⇒ Object
58 59 60 |
# File 'lib/service_skeleton/signal_manager.rb', line 58 def shutdown @r.close end |