Files
foreman/lib/foreman/engine.rb
David Dollar 2dbd3e6be5 initial commit
2010-05-17 01:36:30 -04:00

88 lines
1.9 KiB
Ruby

require "foreman"
require "foreman/process"
class Foreman::Engine
attr_reader :procfile
attr_reader :directory
def initialize(procfile)
@procfile = File.read(procfile)
@directory = File.expand_path(File.dirname(procfile))
end
def processes
@processes ||= begin
procfile.split("\n").inject({}) do |hash, line|
next if line.strip == ""
process = Foreman::Process.new(*line.split(" ", 2))
hash.update(process.name => process)
end
end
end
def start
proctitle "ruby: foreman master"
processes.each do |name, process|
fork process
end
trap("TERM") { kill_and_exit("TERM") }
trap("INT") { kill_and_exit("INT") }
trap("INFO") { print_info }
while true
pid, status = Process.wait2
process = running_processes.delete(pid)
info "exited with code #{status}", process
fork process
end
end
private ######################################################################
def fork(process)
pid = Process.fork do
proctitle "ruby: foreman #{process.name}"
Dir.chdir directory do
system process.command
exit $?.exitstatus || 255
end
end
info "started with pid #{pid}", process
running_processes[pid] = process
end
def kill_and_exit(signal="TERM")
info "termination requested"
running_processes.each do |pid, process|
info "killing pid #{pid}", process
Process.kill(signal, pid)
end
exit 0
end
def info(message, process=nil)
puts "[foreman] [#{Time.now.utc}] [#{process ? process.name : "system"}] #{message}"
end
def print_info
info "currently running processes:"
running_processes.each do |pid, process|
info "pid #{pid}", process
end
end
def running_processes
@running_processes ||= {}
end
def proctitle(title)
$0 = title
end
end