lib/foreman/engine.rb in foreman-0.23.1 vs lib/foreman/engine.rb in foreman-0.24.0

- old
+ new

@@ -1,7 +1,8 @@ require "foreman" require "foreman/process" +require "foreman/procfile" require "foreman/utils" require "pty" require "tempfile" require "timeout" require "term/ansicolor" @@ -17,71 +18,46 @@ extend Term::ANSIColor COLORS = [ cyan, yellow, green, magenta, red ] def initialize(procfile, options={}) - @procfile = read_procfile(procfile) + @procfile = Foreman::Procfile.new(procfile) @directory = File.expand_path(File.dirname(procfile)) @options = options @environment = read_environment_files(options[:env]) end - def processes - @processes ||= begin - @order = [] - procfile.split("\n").inject({}) do |hash, line| - next hash if line.strip == "" - name, command = line.split(/\s*:\s+/, 2) - unless command - warn_deprecated_procfile! - name, command = line.split(/ +/, 2) - end - process = Foreman::Process.new(name, command) - process.color = next_color - @order << process.name - hash.update(process.name => process) - end - end - end - - def process_order - processes - @order.uniq - end - - def processes_in_order - process_order.map do |name| - [name, processes[name]] - end - end - def start proctitle "ruby: foreman master" - processes_in_order.each do |name, process| + processes.each do |process| + process.color = next_color fork process end trap("TERM") { puts "SIGTERM received"; terminate_gracefully } trap("INT") { puts "SIGINT received"; terminate_gracefully } watch_for_termination end def execute(name) + fork procfile[name] - fork processes[name] - trap("TERM") { puts "SIGTERM received"; terminate_gracefully } trap("INT") { puts "SIGINT received"; terminate_gracefully } watch_for_termination end + def processes + procfile.processes + end + def port_for(process, num, base_port=nil) base_port ||= 5000 - offset = processes_in_order.map { |p| p.first }.index(process.name) * 100 + offset = procfile.process_names.index(process.name) * 100 base_port.to_i + offset + num - 1 end private ###################################################################### @@ -132,10 +108,28 @@ running_processes.each do |pid, process| Process.kill(signal, pid) rescue Errno::ESRCH end end + def terminate_gracefully + info "sending SIGTERM to all processes" + kill_all "SIGTERM" + Timeout.timeout(3) { Process.waitall } + rescue Timeout::Error + info "sending SIGKILL to all processes" + kill_all "SIGKILL" + end + + def watch_for_termination + pid, status = Process.wait2 + process = running_processes.delete(pid) + info "process terminated", process + terminate_gracefully + kill_all + rescue Errno::ECHILD + end + def info(message, process=nil) print process.color if process print "#{Time.now.strftime("%H:%M:%S")} #{pad_process_name(process)} | " print Term::ANSIColor.reset print message.chomp @@ -147,63 +141,35 @@ exit 1 end def longest_process_name @longest_process_name ||= begin - longest = processes.keys.map { |name| name.length }.sort.last + longest = procfile.process_names.map { |name| name.length }.sort.last longest = 6 if longest < 6 # system longest end end def pad_process_name(process) name = process ? "#{ENV["PS"]}" : "system" name.ljust(longest_process_name + 3) # add 3 for process number padding end - def print_info - info "currently running processes:" - running_processes.each do |pid, process| - info "pid #{pid}", process - end - end - def proctitle(title) $0 = title end - def read_procfile(procfile) - File.read(procfile) - end - - def watch_for_termination - pid, status = Process.wait2 - process = running_processes.delete(pid) - info "process terminated", process - terminate_gracefully - kill_all - rescue Errno::ECHILD - end - def running_processes @running_processes ||= {} end def next_color @current_color ||= -1 @current_color += 1 @current_color >= COLORS.length ? "" : COLORS[@current_color] end - def warn_deprecated_procfile! - return if @already_warned_deprecated - @already_warned_deprecated = true - puts "!!! This format of Procfile is deprecated, and will not work starting in v0.12" - puts "!!! Use a colon to separate the process name from the command" - puts "!!! e.g. web: thin start" - end - def read_environment_files(filenames) environment = {} (filenames || "").split(",").map(&:strip).each do |filename| error "No such file: #{filename}" unless File.exists?(filename) @@ -221,17 +187,8 @@ if line =~ /\A([A-Za-z_]+)=(.*)\z/ hash[$1] = $2 end hash end - end - - def terminate_gracefully - info "sending SIGTERM to all processes" - kill_all "SIGTERM" - Timeout.timeout(3) { Process.waitall } - rescue Timeout::Error - info "sending SIGKILL to all processes" - kill_all "SIGKILL" end end