class Chimp::ChimpDaemon

Attributes

bind_address[RW]
chimp_queue[RW]
concurrency[RW]
debug[RW]
delay[RW]
dry_run[RW]
logfile[RW]
port[RW]
proc_counter[RW]
queue[R]
retry_count[RW]
running[R]
semaphore[RW]
server[RW]
verbose[RW]

Public Class Methods

new() click to toggle source
# File lib/right_chimp/daemon/chimp_daemon.rb, line 17
def initialize
  @verbose     = false
  @debug       = false
  @port        = 9055
  @bind_address = 'localhost'
  @concurrency = 50
  @delay       = 0
  @retry_count = 0
  @threads     = []
  @running     = false
  @queue       = ChimpQueue.instance
  @chimp_queue = Queue.new
  @semaphore   = Mutex.new

  @proc_counter = 0

  # Connect to the API
  Connection.instance
end

Public Instance Methods

help() click to toggle source

Print out help information

# File lib/right_chimp/daemon/chimp_daemon.rb, line 123
def help
  puts
  puts  "chimpd -- a RightScale Platform command-line tool"
  puts
  puts  "Syntax: chimpd [--logfile=<name>] [--concurrency=<c>] [--delay=<d>] [--retry=<r>] [--port=<p>] [--bind-address=<addr> ] [--verbose]"
  puts
  puts  "Options:"
  puts
  puts  " --logfile=<name>            Specifiy the desired log location"
  puts  " --concurrency=<n>           Specify the level of concurrent actions"
  puts  " --delay=<n>                 Specify the number of seconds to wait before executing the action"
  puts  " --retry=<r>                 Specify the number of times chimpd should retry executing the action"
  puts
  puts  " --verbose                   Run chimpd in verbose mode."
  puts  " --quiet                     Supress non-essential output"
  puts
  puts  " --port=<port>               Specify the port number for chimpd to listen on (default: 9055)"
  puts  " --bind-address=<addr>       Specify an interface address for chimpd to bind to.  0.0.0.0 allows all, default is 'localhost'"
  puts
  puts  " --help                      Displays this menu"
  puts
  exit 0
end
install_signal_handlers() click to toggle source

Trap signals to exit cleanly

# File lib/right_chimp/daemon/chimp_daemon.rb, line 205
def install_signal_handlers
  ['INT', 'TERM'].each do |signal|
    trap(signal) do
      puts "Terminating..."
      self.quit
    end
  end
end
parse_command_line() click to toggle source

Parse chimpd command line options

# File lib/right_chimp/daemon/chimp_daemon.rb, line 55
def parse_command_line
  begin
    opts = GetoptLong.new(
      [ '--logfile', '-l',      GetoptLong::REQUIRED_ARGUMENT ],
      [ '--verbose', '-v',      GetoptLong::NO_ARGUMENT ],
      [ '--quiet',   '-q',      GetoptLong::NO_ARGUMENT ],
      [ '--concurrency', '-c',  GetoptLong::REQUIRED_ARGUMENT ],
      [ '--delay', '-d',        GetoptLong::REQUIRED_ARGUMENT ],
      [ '--retry', '-y',        GetoptLong::REQUIRED_ARGUMENT ],
      [ '--port', '-p',         GetoptLong::REQUIRED_ARGUMENT ],
      [ '--bind-address', '-b', GetoptLong::REQUIRED_ARGUMENT ],
      [ '--help', '-h',         GetoptLong::NO_ARGUMENT ],
      [ '--exit', '-x',                             GetoptLong::NO_ARGUMENT ]
    )

    opts.each do |opt, arg|
      case opt
        when '--logfile', '-l'
          @logfile = arg
          Log.logger = Logger.new(@logfile)
        when '--concurrency', '-c'
          @concurrency = arg.to_i
        when '--delay', '-d'
          @delay = arg.to_i
        when '--retry', '-y'
          @retry_count = arg.to_i
        when '--verbose', '-v'
          @verbose = true
        when '--quiet',   '-q'
          @quiet = true
        when '--port', '-p'
          @port = arg
        when '--bind-address', '-b'
          @bind_address = arg.to_s
        when '--help', '-h'
          help
        when '--exit', '-x'
          uri = "http://localhost:#{@port}/admin"
          response = RestClient.post uri, { 'shutdown' => true }.to_yaml
          exit 0
      end
    end
  rescue GetoptLong::InvalidOption => ex
    puts "Syntax: chimpd [--logfile=<name>] [--concurrency=<c>] [--delay=<d>] [--retry=<r>] [--port=<p>] [--bind-address=<addr> ] [--verbose]"
    exit 1
  end

  #
  # Set up logging/verbosity
  #
  Chimp.set_verbose(@verbose, @quiet)

  if not @verbose
    ENV['REST_CONNECTION_LOG'] = "/dev/null"
    ENV['RESTCLIENT_LOG'] = "/dev/null"
    Log.threshold= Logger::INFO
  else
    Log.threshold= Logger::DEBUG
  end

  if @quiet
    Log.threshold = Logger::WARN
  end
end
quit() click to toggle source

Quit by waiting for all chimp jobs to finish, not allowing new jobs on the queue, and killing the web server.

# File lib/right_chimp/daemon/chimp_daemon.rb, line 218
def quit
  @running = false
  @server.shutdown
  sleep 5
  exit 0
end
run() click to toggle source

Main entry point for chimpd command line application

# File lib/right_chimp/daemon/chimp_daemon.rb, line 40
def run
  install_signal_handlers
  parse_command_line

  # puts "chimpd #{VERSION} launching with #{@concurrency} workers"
  Log.info 'Loading... please wait'
  spawn_queue_runner
  spawn_webserver
  spawn_chimpd_submission_processor
  run_forever
end
run_forever() click to toggle source

Process requests forever until we're killed

# File lib/right_chimp/daemon/chimp_daemon.rb, line 193
def run_forever
  @running = true
  while @running
    @threads.each do |t|
      t.join(5)
    end
  end
end
spawn_chimpd_submission_processor() click to toggle source

Spawn threads to process submitted requests

# File lib/right_chimp/daemon/chimp_daemon.rb, line 228
def spawn_chimpd_submission_processor
  n = @concurrency/4
  n = 10 if n < 10
  Log.debug "Logging into API..."

  #
  # There is a race condition logging in with rest_connection.
  # As a workaround, do a tag query first thing when chimpd starts.
  #
  begin
    c = Chimp.new
    c.interactive = false
    c.quiet = true
    #c.tags = ["bogus:tag=true"]
    c.run
  rescue StandardError
  end

  puts "chimpd #{VERSION} launched with #{@concurrency} workers"

  Log.debug "Spawning #{n} submission processing threads"

  (1..n).each do |n|
    @threads ||=[]
    @threads << Thread.new {
      while true
        begin

          queued_request = @chimp_queue.pop
          group = queued_request.group
          queued_request.interactive = false
          tasks = queued_request.process
          tasks.each do |task|
            ChimpQueue.instance.push(group, task)
          end

        rescue StandardError => ex
            puts ex.backtrace
          Log.error " submission processor: group=\"#{group}\" script=\"#{queued_request.script}\": #{ex}"
        end
      end
    }
  end
end
spawn_queue_runner() click to toggle source

Spawn the ChimpQueue threads

# File lib/right_chimp/daemon/chimp_daemon.rb, line 150
def spawn_queue_runner
  @queue.max_threads = @concurrency
  @queue.delay = @delay
  @queue.retry_count = @retry_count
  @queue.start
  @running = true
end
spawn_webserver() click to toggle source

Spawn a WEBrick Web server

# File lib/right_chimp/daemon/chimp_daemon.rb, line 161
def spawn_webserver
  opts = {
    :BindAddress  => @bind_address,
    :Port         => @port,
    :MaxClients   => 500,
    :RequestTimeout => 120,
    :DoNotReverseLookup => true
  }

  if not @verbose
    opts[:Logger] = WEBrick::Log.new("/dev/null")
    opts[:AccessLog] = [nil, nil]
  end

  @server = ::WEBrick::HTTPServer.new(opts)
  @server.mount('/',         DisplayServlet)
  @server.mount('/display',  DisplayServlet)
  @server.mount('/job',      JobServlet)
  @server.mount('/group',    GroupServlet)
  @server.mount('/admin',    AdminServlet)

  #
  # WEBrick threads
  #
  @threads << Thread.new(1001) do
    @server.start
  end
end