module Resque::Pool::CLI
Public Instance Methods
daemonize()
click to toggle source
# File lib/resque/pool/cli.rb, line 79 def daemonize raise 'First fork failed' if (pid = fork) == -1 exit unless pid.nil? Process.setsid raise 'Second fork failed' if (pid = fork) == -1 exit unless pid.nil? end
manage_pidfile(pidfile)
click to toggle source
# File lib/resque/pool/cli.rb, line 99 def manage_pidfile(pidfile) return unless pidfile pid = Process.pid if File.exist? pidfile if process_still_running? pidfile raise "Pidfile already exists at #{pidfile} and process is still running." else File.delete pidfile end else FileUtils.mkdir_p File.dirname(pidfile) end File.open pidfile, "w" do |f| f.write pid end at_exit do if Process.pid == pid File.delete pidfile end end end
parse_options(argv=nil)
click to toggle source
# File lib/resque/pool/cli.rb, line 24 def parse_options(argv=nil) opts = {} parser = OptionParser.new do |opt| opt.banner = <<-EOS.gsub(/^ /, '') resque-pool is the best way to manage a group (pool) of resque workers When daemonized, stdout and stderr default to resque-pool.stdxxx.log files in the log directory and pidfile defaults to resque-pool.pid in the current dir. Usage: resque-pool [options] where [options] are: EOS opt.on('-c', '--config PATH', "Alternate path to config file") { |c| opts[:config] = c } opt.on('-a', '--appname NAME', "Alternate appname") { |c| opts[:appname] = c } opt.on("-d", '--daemon', "Run as a background daemon") { opts[:daemon] = true opts[:stdout] ||= "log/resque-pool.stdout.log" opts[:stderr] ||= "log/resque-pool.stderr.log" opts[:pidfile] ||= "tmp/pids/resque-pool.pid" unless opts[:no_pidfile] } opt.on("-k", '--kill-others', "Shutdown any other Resque Pools on startup") { opts[:killothers] = true } opt.on('-o', '--stdout FILE', "Redirect stdout to logfile") { |c| opts[:stdout] = c } opt.on('-e', '--stderr FILE', "Redirect stderr to logfile") { |c| opts[:stderr] = c } opt.on('--nosync', "Don't sync logfiles on every write") { opts[:nosync] = true } opt.on("-p", '--pidfile FILE', "PID file location") { |c| opts[:pidfile] = c opts[:no_pidfile] = false } opt.on('--no-pidfile', "Force no pidfile, even if daemonized") { opts[:pidfile] = nil opts[:no_pidfile] = true } opt.on('-l', '--lock FILE' "Open a shared lock on a file") { |c| opts[:lock_file] = c } opt.on("-H", "--hot-swap", "Set appropriate defaults to hot-swap a new pool for a running pool") {|c| opts[:pidfile] = nil opts[:no_pidfile] = true opts[:lock_file] ||= "tmp/resque-pool.lock" opts[:killothers] = true } opt.on("-E", '--environment ENVIRONMENT', "Set RAILS_ENV/RACK_ENV/RESQUE_ENV") { |c| opts[:environment] = c } opt.on("-s", '--spawn-delay MS', Integer, "Delay in milliseconds between spawning missing workers") { |c| opts[:spawn_delay] = c } opt.on('--term-graceful-wait', "On TERM signal, wait for workers to shut down gracefully") { opts[:term_graceful_wait] = true } opt.on('--term-graceful', "On TERM signal, shut down workers gracefully") { opts[:term_graceful] = true } opt.on('--term-immediate', "On TERM signal, shut down workers immediately (default)") { opts[:term_immediate] = true } opt.on('--single-process-group', "Workers remain in the same process group as the master") { opts[:single_process_group] = true } opt.on("-h", "--help", "Show this.") { puts opt; exit } opt.on("-v", "--version", "Show Version"){ puts "resque-pool #{VERSION} (c) nicholas a. evans"; exit} end parser.parse!(argv || parser.default_argv) opts end
process_still_running?(pidfile)
click to toggle source
# File lib/resque/pool/cli.rb, line 121 def process_still_running?(pidfile) old_pid = open(pidfile).read.strip.to_i old_pid > 0 && Process.kill(0, old_pid) rescue Errno::ESRCH false rescue Errno::EPERM true rescue ::Exception => e $stderr.puts "While checking if PID #{old_pid} is running, unexpected #{e.class}: #{e}" true end
redirect(opts)
click to toggle source
# File lib/resque/pool/cli.rb, line 133 def redirect(opts) $stdin.reopen '/dev/null' if opts[:daemon] # need to reopen as File, or else Resque::Pool::Logging.reopen_logs! won't work out = File.new(opts[:stdout], "a") if opts[:stdout] && !opts[:stdout].empty? err = File.new(opts[:stderr], "a") if opts[:stderr] && !opts[:stderr].empty? $stdout.reopen out if out $stderr.reopen err if err $stdout.sync = $stderr.sync = true unless opts[:nosync] end
run()
click to toggle source
# File lib/resque/pool/cli.rb, line 13 def run opts = parse_options obtain_shared_lock opts[:lock_file] daemonize if opts[:daemon] manage_pidfile opts[:pidfile] redirect opts setup_environment opts set_pool_options opts start_pool end
set_pool_options(opts)
click to toggle source
TODO: global variables are not the best way
# File lib/resque/pool/cli.rb, line 144 def set_pool_options(opts) if opts[:daemon] Resque::Pool.handle_winch = true end if opts[:term_graceful_wait] Resque::Pool.term_behavior = "graceful_worker_shutdown_and_wait" elsif opts[:term_graceful] Resque::Pool.term_behavior = "graceful_worker_shutdown" elsif ENV["TERM_CHILD"] log "TERM_CHILD enabled, so will user 'term-graceful-and-wait' behaviour" Resque::Pool.term_behavior = "graceful_worker_shutdown_and_wait" end if ENV.include?("DYNO") && !ENV["TERM_CHILD"] log "WARNING: Are you running on Heroku? You should probably set TERM_CHILD=1" end if opts[:spawn_delay] Resque::Pool.spawn_delay = opts[:spawn_delay] * 0.001 end Resque::Pool.kill_other_pools = !!opts[:killothers] end
setup_environment(opts)
click to toggle source
# File lib/resque/pool/cli.rb, line 165 def setup_environment(opts) Resque::Pool.app_name = opts[:appname] if opts[:appname] ENV["RACK_ENV"] = ENV["RAILS_ENV"] = ENV["RESQUE_ENV"] = opts[:environment] if opts[:environment] Resque::Pool.log "Resque Pool running in #{ENV["RAILS_ENV"] || "development"} environment" ENV["RESQUE_POOL_CONFIG"] = opts[:config] if opts[:config] Resque::Pool.single_process_group = opts[:single_process_group] end
start_pool()
click to toggle source
# File lib/resque/pool/cli.rb, line 173 def start_pool require 'rake' self.const_set :RakeApp, Class.new(Rake::Application) { def default_task_name # :nodoc: "resque:pool" end } Rake.application = RakeApp.new require 'resque/pool/tasks' Rake.application.init Rake.application.load_rakefile Rake.application["resque:pool"].invoke end