class Pebbles::River::DaemonHelper

Simple helper class for easily writing daemons that run multiple queue workers. Handles command line parsing and daemonization.

Adapter should support:

Attributes

logger[RW]

Public Class Methods

new(adapter, options = {}) click to toggle source
# File lib/pebbles/river/daemon_helper.rb, line 41
def initialize(adapter, options = {})
  @adapter = adapter

  @name = @adapter.name if @adapter.respond_to?(:name)
  @name ||= File.basename($0).gsub(/\.rb$/, '')

  @logger = options.fetch(:logger, Logger.new($stderr))
end
run(adapter, options = {}) click to toggle source
# File lib/pebbles/river/daemon_helper.rb, line 37
def self.run(adapter, options = {})
  new(adapter, options).run
end

Public Instance Methods

run() click to toggle source
# File lib/pebbles/river/daemon_helper.rb, line 50
def run
  Mercenary.program(@name) do |p|
    p.syntax "#{@name} <subcommand> [OPTION ...]"
    p.command(:start) do |c|
      c.syntax 'start'
      c.description 'Starts daemon'
      c.option :daemonize, '-d', '--daemon', 'To daemonize; otherwise will run synchronously.'
      c.option :pidfile, '-p', '--pidfile PIDFILE', 'Path to pid file.'
      c.option :workers, Integer, '-w', '--workers N', 'Set number of workers per queue (defaults to 1).'
      c.action do |_, options|
        handle_exceptions do
          start(options)
        end
      end
      if @adapter.respond_to?(:configure_start_command)
        @adapter.configure_start_command(c)
      end
    end
    p.command(:stop) do |c|
      c.syntax 'stop'
      c.description 'Stops daemon'
      c.option :pidfile, '-p', '--pidfile PIDFILE', 'Path to pid file.'
      c.action do |_, options|
        handle_exceptions do
          stop(options)
        end
      end
    end
    p.command(:status) do |c|
      c.syntax 'status'
      c.description 'Prints daemon status'
      c.option :pidfile, '-p', '--pidfile PIDFILE', 'Path to pid file.'
      c.action do |_, options|
        handle_exceptions do
          status(options)
        end
      end
    end
  end

  if ARGV.any?
    abort "Unknown command '#{ARGV.first}'."
  else
    abort "Run with -h for help."
  end
end

Private Instance Methods

get_daemon(options) click to toggle source
# File lib/pebbles/river/daemon_helper.rb, line 140
def get_daemon(options)
  unless options[:pidfile]
    abort "Specify pidfile with --pidfile."
  end

  Servolux::Daemon.new(
    name: @name,
    pid_file: options[:pidfile],
    logger: @logger,
    startup_command: '/bin/true',
    nochdir: true)
end
handle_exceptions() { || ... } click to toggle source
# File lib/pebbles/river/daemon_helper.rb, line 172
def handle_exceptions(&block)
  yield
rescue => e
  if @logger.respond_to?(:exception)
    @logger.exception(e)
  end
  $stderr.puts "Error: #{e.class}: #{e}"
  $stderr.puts e.backtrace.map { |s| "\t#{s}\n" }.join
  exit(1)
end
new_daemon(options) click to toggle source
# File lib/pebbles/river/daemon_helper.rb, line 153
def new_daemon(options)
  unless options[:pidfile]
    abort "Specify pidfile with --pidfile."
  end

  supervisor = Pebbles::River::Supervisor.new(@name,
    pid_file: options[:pidfile],
    logger: @logger,
    worker_count: options[:workers])

  @adapter.configure_supervisor(supervisor)

  supervisor.start_workers

  Servolux::Daemon.new(
    server: supervisor,
    nochdir: true)
end
start(options) click to toggle source
# File lib/pebbles/river/daemon_helper.rb, line 99
def start(options)
  if @adapter.respond_to?(:on_start)
    @adapter.on_start(options, self)
  end

  daemon = new_daemon(options)
  if daemon.alive?
    abort "#{daemon.name} is already running."
  end
  if options[:daemonize]
    print "Starting #{daemon.name}"
    daemon.startup
    puts ", done."
  else
    daemon.server.startup
  end
  exit
end
status(options) click to toggle source
# File lib/pebbles/river/daemon_helper.rb, line 130
def status(options)
  daemon = get_daemon(options)
  if daemon.alive?
    puts "#{daemon.name} is running."
  else
    puts "#{daemon.name} is not running."
  end
  exit(daemon.alive? ? 0 : 1)
end
stop(options) click to toggle source
# File lib/pebbles/river/daemon_helper.rb, line 118
def stop(options)
  daemon = get_daemon(options)
  unless daemon.alive?
    puts "#{daemon.name} is not running."
  else
    print "Stopping #{daemon.name}"
    daemon.shutdown
    puts ", done."
  end
  exit
end