class Strelka::MultiRunner
Load multiple simultaneous Strelka
handlers (of a single type) with proper signal handling.
Constants
- QUEUE_SIGS
Signals we understand.
Attributes
app_class[R]
The class name of the handler.
handler_pids[R]
The child handler pids.
number[R]
How many handler children to manage.
running[R]
In this instance currently managing children?
Public Class Methods
new( app_class, number=2 )
click to toggle source
Create a new multirunner instance given a handler app_class
, and the number
of instances to start.
# File lib/strelka/multirunner.rb, line 24 def initialize( app_class, number=2 ) @handler_pids = [] @running = false @app_class = app_class @number = number self.set_up_signal_handling end
Public Instance Methods
run()
click to toggle source
Start the child handlers via fork(), block for signals.
# File lib/strelka/multirunner.rb, line 47 def run @running = true # Set up traps for common signals self.set_signal_traps( *QUEUE_SIGS ) self.log.debug "Starting multirunner loop..." self.spawn_children while self.running self.reap_children if self.wait_for_signals end self.log.debug "Ending multirunner." # Restore the default signal handlers self.reset_signal_traps( *QUEUE_SIGS ) return end
Protected Instance Methods
handle_signal( sig )
click to toggle source
Handle signals.
# File lib/strelka/multirunner.rb, line 120 def handle_signal( sig ) self.log.debug "Handling signal %s in PID %d" % [ sig, Process.pid ] case sig when :INT, :TERM, :QUIT if @running self.log.warn "%s signal: graceful shutdown" % [ sig ] self.kill_children( sig ) @running = false else self.ignore_signals self.log.warn "%s signal: forceful shutdown" % [ sig ] self.kill_children( :KILL ) exit!( 255 ) end when :CHLD self.log.info "Got SIGCHLD." # Just need to wake up, nothing else necessary else self.log.warn "Unhandled signal %s" % [ sig ] end end
kill_children( signal=:TERM )
click to toggle source
Kill all current children with the specified signal
. Returns true
if the signal was sent to one or more children.
# File lib/strelka/multirunner.rb, line 99 def kill_children( signal=:TERM ) return false if self.handler_pids.empty? self.log.info "Sending %s signal to %d task pids: %p." % [ signal, self.handler_pids.length, self.handler_pids ] self.handler_pids.each do |pid| begin Process.kill( signal, pid ) rescue Errno::ESRCH => err self.log.error "%p when trying to %s child %d: %s" % [ err.class, signal, pid, err.message ] end end return true rescue Errno::ESRCH self.log.debug "Ignoring signals to unreaped children." end
reap_children()
click to toggle source
Clean up after any children that have died.
# File lib/strelka/multirunner.rb, line 86 def reap_children pid, status = Process.waitpid2( -1, Process::WNOHANG|Process::WUNTRACED ) self.log.debug " waitpid2 returned: [ %p, %p ]" % [ pid, status ] while pid self.handler_pids.delete( pid ) pid, status = Process.waitpid2( -1, Process::WNOHANG|Process::WUNTRACED ) self.log.debug " waitpid2 returned: [ %p, %p ]" % [ pid, status ] end end
spawn_children()
click to toggle source
Start the handlers using fork().
# File lib/strelka/multirunner.rb, line 72 def spawn_children self.number.times do Strelka.call_before_fork_hooks pid = Process.fork do Process.setpgrp self.app_class.run end self.handler_pids << pid Process.setpgid( pid, 0 ) end end