Class: Smith::SelfPipe
- Inherits:
-
Object
- Object
- Smith::SelfPipe
- Includes:
- Logger
- Defined in:
- lib/smith/self_pipe.rb
Instance Method Summary collapse
-
#initialize(agent) ⇒ SelfPipe
constructor
A new instance of SelfPipe.
-
#install_signal_handler(signal, position = :end, &blk) ⇒ Object
Adds a signal handler proc to the list of signal_handlers.
-
#setup_signal_handlers ⇒ Object
Set up the mechanics required to implement the self pipe trick.
Methods included from Logger
Constructor Details
#initialize(agent) ⇒ SelfPipe
Returns a new instance of SelfPipe.
6 7 8 9 10 11 12 13 14 |
# File 'lib/smith/self_pipe.rb', line 6 def initialize(agent) @agent = agent @signal_handlers = Hash.new { |h,k| h[k] = Array.new } @signal_handler_queue = [] @signal_handler_pipe_reader, @signal_handler_pipe_writer = IO.pipe setup_signal_handlers end |
Instance Method Details
#install_signal_handler(signal, position = :end, &blk) ⇒ Object
Adds a signal handler proc to the list of signal_handlers. When a signal is received all signal handlers are called in reverse order.
24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/smith/self_pipe.rb', line 24 def install_signal_handler(signal, position=:end, &blk) raise ArgumentError, "Unknown position: #{position}" if ![:beginning, :end].include?(position) logger.debug { "Installing signal handler for #{signal}" } @signal_handlers[signal].insert((position == :beginning) ? 0 : -1, blk) Signal.trap(signal) { @signal_handler_pipe_writer.write_nonblock('.') @signal_handler_queue << signal } end |
#setup_signal_handlers ⇒ Object
Set up the mechanics required to implement the self pipe trick.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/smith/self_pipe.rb', line 37 def setup_signal_handlers # The Module declaration here will only close over local variables so we # need to assign self to a local variable to get access to the agent itself. clazz = self EM.attach(@signal_handler_pipe_reader, Module.new { define_method :receive_data do |_| handlers = clazz.instance_variable_get(:@signal_handlers) queue = clazz.instance_variable_get(:@signal_handler_queue) signal = queue.pop clazz.send(:logger).debug { "Running signal handlers for: #{signal}" } handlers[signal].each { |handler| handler.call(signal) } end }) end |