Class: Chimp::ChimpDaemon

Inherits:
Object
  • Object
show all
Includes:
Singleton
Defined in:
lib/right_chimp/daemon/ChimpDaemon.rb

Defined Under Namespace

Classes: AdminServlet, DisplayServlet, GenericServlet, GroupServlet, JobServlet

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeChimpDaemon

Returns a new instance of ChimpDaemon.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/right_chimp/daemon/ChimpDaemon.rb', line 16

def initialize
  @verbose     = false
  @debug       = false
  @port        = 9055
  @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

Instance Attribute Details

#chimp_queueObject

Returns the value of attribute chimp_queue.



10
11
12
# File 'lib/right_chimp/daemon/ChimpDaemon.rb', line 10

def chimp_queue
  @chimp_queue
end

#concurrencyObject

Returns the value of attribute concurrency.



10
11
12
# File 'lib/right_chimp/daemon/ChimpDaemon.rb', line 10

def concurrency
  @concurrency
end

#debugObject

Returns the value of attribute debug.



10
11
12
# File 'lib/right_chimp/daemon/ChimpDaemon.rb', line 10

def debug
  @debug
end

#delayObject

Returns the value of attribute delay.



10
11
12
# File 'lib/right_chimp/daemon/ChimpDaemon.rb', line 10

def delay
  @delay
end

#dry_runObject

Returns the value of attribute dry_run.



10
11
12
# File 'lib/right_chimp/daemon/ChimpDaemon.rb', line 10

def dry_run
  @dry_run
end

#logfileObject

Returns the value of attribute logfile.



10
11
12
# File 'lib/right_chimp/daemon/ChimpDaemon.rb', line 10

def logfile
  @logfile
end

#portObject

Returns the value of attribute port.



10
11
12
# File 'lib/right_chimp/daemon/ChimpDaemon.rb', line 10

def port
  @port
end

#proc_counterObject

Returns the value of attribute proc_counter.



10
11
12
# File 'lib/right_chimp/daemon/ChimpDaemon.rb', line 10

def proc_counter
  @proc_counter
end

#queueObject (readonly)

Returns the value of attribute queue.



12
13
14
# File 'lib/right_chimp/daemon/ChimpDaemon.rb', line 12

def queue
  @queue
end

#retry_countObject

Returns the value of attribute retry_count.



10
11
12
# File 'lib/right_chimp/daemon/ChimpDaemon.rb', line 10

def retry_count
  @retry_count
end

#runningObject (readonly)

Returns the value of attribute running.



12
13
14
# File 'lib/right_chimp/daemon/ChimpDaemon.rb', line 12

def running
  @running
end

#semaphoreObject

Returns the value of attribute semaphore.



10
11
12
# File 'lib/right_chimp/daemon/ChimpDaemon.rb', line 10

def semaphore
  @semaphore
end

#verboseObject

Returns the value of attribute verbose.



10
11
12
# File 'lib/right_chimp/daemon/ChimpDaemon.rb', line 10

def verbose
  @verbose
end

Instance Method Details

#helpObject

Print out help information



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/right_chimp/daemon/ChimpDaemon.rb', line 118

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>] [--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
  puts  " --help                      Displays this menu"
  puts
  exit 0
end

#install_signal_handlersObject

Trap signals to exit cleanly



199
200
201
202
203
204
205
206
# File 'lib/right_chimp/daemon/ChimpDaemon.rb', line 199

def install_signal_handlers
  ['INT', 'TERM'].each do |signal|
    trap(signal) do
      puts "Terminating..."
      self.quit
    end
  end
end

#parse_command_lineObject

Parse chimpd command line options



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/right_chimp/daemon/ChimpDaemon.rb', line 53

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 ],
      [ '--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 '--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>] [--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

#quitObject

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



212
213
214
215
216
217
# File 'lib/right_chimp/daemon/ChimpDaemon.rb', line 212

def quit
  @running = false
  @server.shutdown
  sleep 5
  exit 0
end

#runObject

Main entry point for chimpd command line application



38
39
40
41
42
43
44
45
46
47
48
# File 'lib/right_chimp/daemon/ChimpDaemon.rb', line 38

def run
  install_signal_handlers
  parse_command_line

  #puts "chimpd #{VERSION} launching with #{@concurrency} workers"
  puts "Loading... please wait"
  spawn_queue_runner
  spawn_webserver
  spawn_chimpd_submission_processor
  run_forever
end

#run_foreverObject

Process requests forever until we’re killed



187
188
189
190
191
192
193
194
# File 'lib/right_chimp/daemon/ChimpDaemon.rb', line 187

def run_forever
  @running = true
  while @running
    @threads.each do |t|
      t.join(5)
    end
  end
end

#spawn_chimpd_submission_processorObject

Spawn threads to process submitted requests



222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
# File 'lib/right_chimp/daemon/ChimpDaemon.rb', line 222

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_runnerObject

Spawn the ChimpQueue threads



144
145
146
147
148
149
150
# File 'lib/right_chimp/daemon/ChimpDaemon.rb', line 144

def spawn_queue_runner
  @queue.max_threads = @concurrency
  @queue.delay = @delay
  @queue.retry_count = @retry_count
  @queue.start
  @running = true
end

#spawn_webserverObject

Spawn a WEBrick Web server



155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/right_chimp/daemon/ChimpDaemon.rb', line 155

def spawn_webserver
  opts = {
    :BindAddress  => "localhost",
    :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