class Shoryuken::Later::CLI
Public Instance Methods
run(args)
click to toggle source
# File lib/shoryuken/later/cli.rb, line 19 def run(args) @self_read, @self_write = IO.pipe %w[INT TERM USR1 USR2].each do |sig| trap sig do @self_write.puts(sig) end end setup_options(args) do |cli_options| # this needs to happen before configuration is parsed, since it may depend on Rails env load_rails if cli_options[:rails] end initialize_logger require_workers validate! daemonize write_pid Shoryuken::Logging.with_context '[later]' do logger.info 'Starting' start end end
Protected Instance Methods
poll_tables()
click to toggle source
# File lib/shoryuken/later/cli.rb, line 46 def poll_tables logger.debug "Polling schedule tables" @pollers.each do |poller| poller.poll end logger.debug "Polling done" end
Private Instance Methods
daemonize()
click to toggle source
# File lib/shoryuken/later/cli.rb, line 102 def daemonize return unless Shoryuken::Later.options[:daemon] raise ArgumentError, "You really should set a logfile if you're going to daemonize" unless Shoryuken::Later.options[:logfile] files_to_reopen = [] ObjectSpace.each_object(File) do |file| files_to_reopen << file unless file.closed? end Process.daemon(true, true) files_to_reopen.each do |file| begin file.reopen file.path, "a+" file.sync = true rescue ::Exception end end [$stdout, $stderr].each do |io| File.open(Shoryuken::Later.options[:logfile], 'ab') do |f| io.reopen(f) end io.sync = true end $stdin.reopen('/dev/null') initialize_logger end
handle_signal(sig)
click to toggle source
# File lib/shoryuken/later/cli.rb, line 192 def handle_signal(sig) logger.info "Got #{sig} signal" case sig when 'USR1' logger.info "Received USR1, will soft shutdown down" @timers.cancel @timers = nil else logger.info "Received #{sig}, will shutdown down" raise Interrupt end end
initialize_aws()
click to toggle source
# File lib/shoryuken/later/cli.rb, line 266 def initialize_aws # aws-sdk tries to load the credentials from the ENV variables: AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY # when not explicit supplied return if Shoryuken::Later.options[:aws].empty? shoryuken_keys = %i( account_id sns_endpoint sqs_endpoint receive_message) aws_options = Shoryuken::Later.options[:aws].reject do |k, v| shoryuken_keys.include?(k) end credentials = Aws::Credentials.new( aws_options.delete(:access_key_id), aws_options.delete(:secret_access_key)) Aws.config = aws_options.merge(credentials: credentials) end
initialize_logger()
click to toggle source
# File lib/shoryuken/later/cli.rb, line 239 def initialize_logger Shoryuken::Logging.initialize_logger(Shoryuken::Later.options[:logfile]) if Shoryuken::Later.options[:logfile] Shoryuken::Later.logger.level = Logger::DEBUG if Shoryuken::Later.options[:verbose] end
load_rails()
click to toggle source
# File lib/shoryuken/later/cli.rb, line 82 def load_rails # Adapted from: https://github.com/mperham/sidekiq/blob/master/lib/sidekiq/cli.rb require 'rails' if ::Rails::VERSION::MAJOR < 4 require File.expand_path("config/environment.rb") ::Rails.application.eager_load! else # Painful contortions, see 1791 for discussion require File.expand_path("config/application.rb") ::Rails::Application.initializer "shoryuken-later.eager_load" do ::Rails.application.config.eager_load = true end require 'shoryuken/later/active_job_adapter' if defined?(::ActiveJob) require File.expand_path("config/environment.rb") end logger.info "Rails environment loaded" end
parse_config(config_file)
click to toggle source
# File lib/shoryuken/later/cli.rb, line 231 def parse_config(config_file) if File.exist?(config_file) YAML.load(ERB.new(IO.read(config_file)).result) else raise ArgumentError, "Config file #{config_file} does not exist" end end
parse_options(argv)
click to toggle source
# File lib/shoryuken/later/cli.rb, line 141 def parse_options(argv) opts = {later: {}} @parser = OptionParser.new do |o| o.on '-d', '--daemon', 'Daemonize process' do |arg| opts[:daemon] = arg end o.on '-t', '--table TABLE...', 'Table to process' do |arg| Shoryuken::Later.tables << args end o.on '-r', '--require [PATH|DIR]', 'Location of the worker' do |arg| opts[:require] = arg end o.on '-C', '--config PATH', 'Path to YAML config file' do |arg| opts[:config_file] = arg end o.on '-R', '--rails', 'Load Rails' do |arg| opts[:rails] = arg end o.on '-L', '--logfile PATH', 'Path to writable logfile' do |arg| opts[:logfile] = arg end o.on '-P', '--pidfile PATH', 'Path to pidfile' do |arg| opts[:later][:pidfile] = arg end o.on '-v', '--verbose', 'Print more verbose output' do |arg| opts[:verbose] = arg end o.on '-V', '--version', 'Print version and exit' do |arg| puts "Shoryuken::Later #{Shoryuken::Later::VERSION}" exit 0 end end @parser.banner = 'shoryuken-later [options]' @parser.on_tail '-h', '--help', 'Show help' do logger.info @parser exit 1 end @parser.parse!(argv) opts end
require_workers()
click to toggle source
# File lib/shoryuken/later/cli.rb, line 288 def require_workers require Shoryuken::Later.options[:require] if Shoryuken::Later.options[:require] end
setup_options(args) { |options| ... }
click to toggle source
# File lib/shoryuken/later/cli.rb, line 206 def setup_options(args) options = parse_options(args) # yield parsed options in case we need to do more setup before configuration is parsed yield(options) if block_given? config = options[:config_file] ? parse_config(options[:config_file]).deep_symbolize_keys : {} Shoryuken::Later.options[:later].merge!(config.delete(:later) || {}) Shoryuken::Later.options.merge!(config) Shoryuken::Later.options[:later].merge!(options.delete(:later) || {}) Shoryuken::Later.options.merge!(options) # Tables from command line options take precedence... unless Shoryuken::Later.tables.any? tables = Shoryuken::Later.options[:later][:tables] # Use the default table if none were specified in the config file. tables << Shoryuken::Later.default_table if tables.empty? Shoryuken::Later.tables.replace(tables) end end
start()
click to toggle source
# File lib/shoryuken/later/cli.rb, line 56 def start # Initialize the timers and poller. @timers = Timers::Group.new @pollers = Shoryuken::Later.tables.map{|tbl| Poller.new(tbl) } begin # Poll for items on startup, and every :poll_delay poll_tables @timers.every(Shoryuken::Later.poll_delay){ poll_tables } # Loop watching for signals and firing off of timers while @timers interval = @timers.wait_interval readable, writable = IO.select([@self_read], nil, nil, interval) if readable handle_signal readable.first.gets.strip else @timers.fire end end rescue Interrupt @timers.cancel exit 0 end end
validate!()
click to toggle source
# File lib/shoryuken/later/cli.rb, line 245 def validate! raise ArgumentError, 'No tables given to poll' if Shoryuken::Later.tables.empty? if Shoryuken::Later.options[:aws][:access_key_id].nil? && Shoryuken::Later.options[:aws][:secret_access_key].nil? if ENV['AWS_ACCESS_KEY_ID'].nil? && ENV['AWS_SECRET_ACCESS_KEY'].nil? raise ArgumentError, 'No AWS credentials supplied' end end initialize_aws Shoryuken::Later.tables.uniq.each do |table| # validate all tables and AWS credentials consequently begin Shoryuken::Later::Client.tables table rescue Aws::DynamoDB::Errors::ResourceNotFoundException => e raise ArgumentError, "Table '#{table}' does not exist" end end end
write_pid()
click to toggle source
# File lib/shoryuken/later/cli.rb, line 133 def write_pid if path = Shoryuken::Later.options[:later][:pidfile] File.open(path, 'w') do |f| f.puts Process.pid end end end