Skip to content

Instantly share code, notes, and snippets.

@schmurfy
Forked from somic/forking_supervisor.rb
Created January 7, 2013 09:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save schmurfy/4473737 to your computer and use it in GitHub Desktop.
Save schmurfy/4473737 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
#
# forking supervisor - forks workers and replaces dead workers.
# start it in one console, send signals to it from another console.
#
require 'rubygems'
require 'daemons/daemonize'
def logit(msg)
if $worker
puts "#{Time.now} worker[#{$$}] #{msg}"
else
puts "#{Time.now} supervisor[#{$$}] #{msg}"
end
end
def myworker
# this is your worker, it does something useful
loop {
logit "ping"
sleep 20
}
end
def start_worker_daemon
p = Process.fork { $worker = true; myworker }
logit "started worker pid=#{p}"
p
end
if __FILE__ == $0
# starts supervisor
Daemonize.daemonize(logfile_name="/tmp/my.log", app_name="foo") if
ARGV[0] == '-d' # do you want supervisor as a daemon?
logit "started"
pids = Array.new
workers = 3 # how many workers would you like today?
logit "workers = #{workers}"
$shutdown = false
Signal.trap("TERM") {
$shutdown = true
if $worker
# can do some worker cleanup here
logit "Caught SIGTERM. Exiting."
else
logit "caught SIGTERM. Signaling child processes: #{pids.inspect}"
pids.each { |pid|
logit "sending SIGTERM to pid=#{pid}"
Process.kill('TERM', pid)
Process.waitpid(pid)
logit "pid=#{pid} died."
}
logit "All child processes died."
# can do some supervisor cleanup here
end
exit
}
Signal.trap('CLD') {
unless $shutdown
pids.delete(Process.wait)
pids << start_worker_daemon
end
}
while pids.size < workers
pids << start_worker_daemon
end
loop { sleep 0x1000000 } rescue exit
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment