class MailyHerald::CLI

Public Instance Methods

daemon_running?() click to toggle source
# File lib/maily_herald/cli.rb, line 253
def daemon_running?
  read_pid > 0 && Process.kill(0, read_pid)
rescue
  return false
end
daemonize() click to toggle source
# File lib/maily_herald/cli.rb, line 197
def daemonize
  return unless options[:daemon]

  raise ArgumentError, "You really should set a logfile if you're going to daemonize" unless 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(options[:logfile], 'ab') do |f|
      io.reopen(f)
    end
    io.sync = true
  end
  $stdin.reopen('/dev/null')

  initialize_logger
end
initialize_logger() click to toggle source
# File lib/maily_herald/cli.rb, line 102
def initialize_logger
  opts = {
    level: options[:verbose] ? Logger::DEBUG : Logger::INFO,
    progname: "cli",
  }
  opts[:target] = options[:logfile] if options[:logfile]

  MailyHerald::Logging.initialize(opts)
  MailyHerald.logger.info "Started with options: #{options}"
end
kill_daemon() click to toggle source
# File lib/maily_herald/cli.rb, line 259
def kill_daemon
  Process.kill("INT", read_pid) if read_pid > 0
  return true
rescue
  return false
end
options() click to toggle source
# File lib/maily_herald/cli.rb, line 193
def options
  MailyHerald.options
end
paperboy() click to toggle source
# File lib/maily_herald/cli.rb, line 19
def paperboy
  if options[:action] == :stop
    kill_daemon || exit(0)
  elsif options[:action] == :ping
    if daemon_running?
      puts "PONG"
      exit(0)
    else
      puts "No response..."
      exit(1)
    end
  else
    if options[:action] == :restart 
      kill_daemon 
      5.times do
        if daemon_running?
          sleep 2
        else
          break
        end

        exit(0) if daemon_running?
      end
    end
    exit(0) if options[:action] == :start && daemon_running?

    daemonize
    write_pid

    self_read, self_write = IO.pipe

    %w(INT TERM USR1 USR2).each do |sig|
      trap sig do
        self_write.puts(sig)
      end
    end

    # We don't want to load whole app and its initializers just to set up Sidekiq client
    # so let's just do that instead:
    Sidekiq.redis = {url: options[:redis_url], namespace: options[:redis_namespace]}

    redis = MailyHerald.redis
    MailyHerald.logger.info "MailyHerald running in #{RUBY_DESCRIPTION}"

    if !options[:daemon]
      MailyHerald.logger.info 'Starting processing, hit Ctrl-C to stop'
    end

    begin
      worker = Thread.new do
        while true
          unless MailyHerald::Manager.job_enqueued?
            MailyHerald.run_all 
          else
            # TODO: this is not logged
            #MailyHerald.logger.error 'Unable to queue job'
          end

          sleep 20
        end
      end

      while readable_io = IO.select([self_read])
        signal = readable_io.first[0].gets.strip
        handle_signal(signal)
      end
    rescue Interrupt
      MailyHerald.logger.info 'Shutting down'
      worker.exit
      reset_pid
      exit(0)
    end
  end
end
parse(args=ARGV) click to toggle source
# File lib/maily_herald/cli.rb, line 14
def parse(args=ARGV)
  setup_options(args)
  initialize_logger
end
parse_config(cfile) click to toggle source
# File lib/maily_herald/cli.rb, line 184
def parse_config(cfile)
  opts = {}
  if File.exist?(cfile)
    opts = YAML.load(ERB.new(IO.read(cfile)).result)
    opts = opts.merge(opts.delete(@environment) || {})
  end
  opts
end
parse_options(argv) click to toggle source
# File lib/maily_herald/cli.rb, line 113
def parse_options(argv)
  opts = {}
  @parsers = {}

  @parsers[:paperboy] = OptionParser.new do |o|
    o.banner = "maily_herald paperboy [options]"

    o.on "--start", "Start Paperboy daemon" do |arg|
      opts[:action] = :start
      opts[:daemon] = true
    end

    o.on "--stop", "Stop Paperboy daemon" do |arg|
      opts[:action] = :stop
      opts[:daemon] = true
    end

    o.on "--restart", "Restart Paperboy daemon" do |arg|
      opts[:action] = :restart
      opts[:daemon] = true
    end

    o.on "--ping", "Check if Paperboy daemon is running" do |arg|
      opts[:action] = :ping
      opts[:daemon] = true
    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[:pidfile] = arg
    end
  end

  @parsers[:generic] = OptionParser.new do |o|
    o.banner = "maily_herald [paperboy] [options]"

    o.separator ""
    o.separator "Common options:"

    o.on '-c', '--config PATH', "path to YAML config file" do |arg|
      opts[:config_file] = arg
    end

    o.on '-e', '--environment ENV', "Application environment" do |arg|
      opts[:environment] = arg
    end

    o.on "-v", "--verbose", "Print more verbose output" do |arg|
      opts[:verbose] = arg
    end

    o.on_tail "-h", "--help", "Show help" do
      puts @parsers[:generic]
      puts
      puts @paperboy_parser
      exit 1
    end
  end

  if %w{paperboy}.include?(argv.first)
    opts[:mode] = argv.first.to_sym
    @parsers[argv.first.to_sym].parse!(argv)
  end
  @parsers[:generic].parse!(argv)

  opts
end
read_pid() click to toggle source
# File lib/maily_herald/cli.rb, line 237
def read_pid
  if path = options[:pidfile]
    File.read(path).to_i
  end
end
reset_pid() click to toggle source
# File lib/maily_herald/cli.rb, line 243
def reset_pid
  return unless options[:daemon]

  if path = options[:pidfile]
    File.open(path, 'w') do |f|
      f.puts nil
    end
  end
end
setup_options(args) click to toggle source
# File lib/maily_herald/cli.rb, line 94
def setup_options(args)
  cli = parse_options(args)

  set_environment cli[:environment]

  MailyHerald.options = MailyHerald.read_options(cli[:config_file] || "config/maily_herald.yml").merge(cli)
end
write_pid() click to toggle source
# File lib/maily_herald/cli.rb, line 227
def write_pid
  return unless options[:daemon]

  if path = options[:pidfile]
    File.open(path, 'w') do |f|
      f.puts Process.pid
    end
  end
end

Private Instance Methods

handle_signal(sig) click to toggle source
# File lib/maily_herald/cli.rb, line 272
def handle_signal(sig)
  MailyHerald.logger.debug "Got #{sig} signal"
  case sig
  when 'INT'
    # Handle Ctrl-C in JRuby like MRI
    # http://jira.codehaus.org/browse/JRUBY-4637
    raise Interrupt
  when 'TERM'
    # Heroku sends TERM and then waits 10 seconds for process to exit.
    raise Interrupt
  when 'USR1'
    MailyHerald.logger.info "Received USR1, doing nothing..."
  when 'USR2'
    if MailyHerald.options[:logfile]
      MailyHerald.logger.info "Received USR2, reopening log file"
      MailyHerald::Logging.initialize_logger(target: MailyHerald.options[:logfile])
    end
  end
end
set_environment(cli_env) click to toggle source
# File lib/maily_herald/cli.rb, line 268
def set_environment(cli_env)
  @environment = cli_env || ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
end