lib/asir/main.rb in asir-0.2.0 vs lib/asir/main.rb in asir-1.0.1
- old
+ new
@@ -1,43 +1,38 @@
require 'asir'
+require 'asir/environment'
require 'time'
-
module ASIR
class Main
- attr_accessor :verb, :adjective, :object, :identifier
- attr_accessor :config_rb, :config
- attr_accessor :log_dir, :pid_dir
- attr_accessor :verbose
- attr_accessor :exit_code
+ attr_accessor :env, :args, :exit_code
+ # Delegate getter/setters to @env.
+ [ :verb, :adjective, :object, :identifier,
+ :config_rb,
+ :verbose,
+ :log_dir, :log_file,
+ :pid_dir, :pid_file,
+ ].
+ map{|g| [ g, :"#{g}=" ]}.
+ flatten.each do | m |
+ define_method(m) { | *args | @env.send(m, *args) }
+ end
+ attr_accessor :progname
+ # Options:
+ attr_accessor :force
+ # Transport selected from asir.phase = :transport.
+ attr_accessor :transport
+
def initialize
- @verbose = 0
- @progname = File.basename($0)
- @log_dir = find_writable_directory :log_dir,
- ENV['ASIR_LOG_DIR'],
- '/var/log/asir',
- '~/asir/log',
- '/tmp'
- @pid_dir = find_writable_directory :pid_dir,
- ENV['ASIR_PID_DIR'],
- '/var/run/asir',
- '~/asir/run',
- '/tmp'
- @exit_code = 0
+ self.env = ASIR::Environment.new
+ self.progname = File.basename($0)
+ self.exit_code = 0
end
- def find_writable_directory kind, *list
- list.
- reject { | p | ! p }.
- map { | p | File.expand_path(p) }.
- find { | p | File.writable?(p) } or
- raise "Cannot find writable directory for #{kind}"
- end
-
def parse_args! args = ARGV.dup
- @args = args
+ self.args = args
until args.empty?
case args.first
when /^([a-z0-9_]+=)(.*)/i
k, v = $1.to_sym, $2
args.shift
@@ -45,29 +40,33 @@
send(k, v)
else
break
end
end
- @verb, @adjective, @object, @identifier = args.map{|x| x.to_sym}
- @identifier ||= :'0'
+ self.verb, self.adjective, self.object, self.identifier = args.map{|x| x.to_sym}
+ self.identifier ||= :'0'
self
end
+ def config! *args
+ @env.config! *args
+ end
+
def log_str
"#{Time.now.gmtime.iso8601(4)} #{$$} #{log_str_no_time}"
end
def log_str_no_time
- "#{@progname} #{@verb} #{@adjective} #{@object} #{@identifier}"
+ "#{progname} #{verb} #{adjective} #{object} #{identifier}"
end
def run!
unless verb && adjective && object
- @exit_code = 1
+ self.exit_code = 1
return usage!
end
- config!(:config)
+ config!(:configure)
# $stderr.puts "log_file = #{log_file.inspect}"
case self.verb
when :restart
self.verb = :stop
_run_verb! && sleep(1)
@@ -77,32 +76,32 @@
_run_verb!
end
self
rescue ::Exception => exc
$stderr.puts "#{log_str} ERROR\n#{exc.inspect}\n #{exc.backtrace * "\n "}"
- @exit_code += 1
+ self.exit_code += 1
self
end
def _run_verb!
sel = :"#{verb}_#{adjective}_#{object}!"
- if @verbose >= 3
- $stderr.puts "verb = #{verb.inspect}"
- $stderr.puts "adjective = #{adjective.inspect}"
- $stderr.puts "object = #{object.inspect}"
- $stderr.puts "sel = #{sel.inspect}"
+ if verbose >= 3
+ $stderr.puts " verb = #{verb.inspect}"
+ $stderr.puts " adjective = #{adjective.inspect}"
+ $stderr.puts " object = #{object.inspect}"
+ $stderr.puts " sel = #{sel.inspect}"
end
send(sel)
rescue ::Exception => exc
$stderr.puts "#{log_str} ERROR\n#{exc.inspect}\n #{exc.backtrace * "\n "}"
- @exit_code += 1
+ self.exit_code += 1
raise
nil
end
def method_missing sel, *args
- log "method_missing #{sel}" if @verbose >= 3
+ log "method_missing #{sel}" if verbose >= 3
case sel.to_s
when /^start_([^_]+)_worker!$/
_start_worker!
when /^status_([^_]+)_([^_]+)!$/
pid = server_pid
@@ -111,11 +110,18 @@
when /^log_([^_]+)_([^_]+)!$/
puts log_file
when /^taillog_([^_]+)_([^_]+)!$/
exec "tail -f #{log_file.inspect}"
when /^pid_([^_]+)_([^_]+)!$/
- puts "#{pid_file} #{File.read(pid_file) rescue nil}"
+ pid = server_pid rescue nil
+ alive = process_running? pid
+ puts "#{pid_file} #{pid || :NA} #{alive}"
+ when /^alive_([^_]+)_([^_]+)!$/
+ pid = server_pid rescue nil
+ alive = process_running? pid
+ puts "#{pid_file} #{pid || :NA} #{alive}" if @verbose
+ self.exit_code += 1 unless alive
when /^stop_([^_]+)_([^_]+)!$/
kill_server!
else
super
end
@@ -137,24 +143,28 @@
stop
restart
status
log
pid
+ alive
ADJECTIVE-OBJECTs:
beanstalk conduit
beanstalk worker
zmq worker
webrick worker
+ resque conduit
+ resque worker
EXAMPLES:
export ASIR_CONFIG_RB="some_system/asir_config.rb"
asir start beanstalk conduit
asir status beanstalk conduit
asir start webrick worker
+ asir pid webrick worker
asir start beanstalk worker 1
asir start beanstalk worker 2
asir start zmq worker
@@ -162,13 +172,25 @@
asir start zmq worker 2
END
end
def start_beanstalk_conduit!
- fork_server! "beanstalkd"
+ _start_conduit!
end
+ def start_resque_conduit!
+ _start_conduit!
+ end
+
+ def _start_conduit!
+ config!(:environment)
+ self.transport = config!(:transport)
+ fork_server! do
+ transport.start_conduit! :fork => false
+ end
+ end
+
def _start_worker! type = adjective
log "start_worker! #{type}"
type = type.to_s
fork_server! do
transport_file = "asir/transport/#{type}"
@@ -177,58 +199,10 @@
_create_transport ASIR::Transport.const_get(type[0..0].upcase + type[1..-1])
_run_workers!
end
end
- ################################################################
-
- def config_rb
- @config_rb ||=
- File.expand_path(ENV['ASIR_CONFIG_RB'] || 'config/asir_config.rb')
- end
-
- def config_lambda
- @config_lambda ||=
- begin
- file = config_rb
- $stderr.puts "#{log_str} loading #{file} ..." if @verbose >= 1
- expr = File.read(file)
- expr = "begin; lambda do | asir |; #{expr}\n end; end"
- cfg = Object.new.send(:eval, expr, binding, file, 1)
- # cfg = load file
- # $stderr.puts "#{log_str} loading #{file} DONE" if @verbose >= 1
- raise "#{file} did not return a Proc, returned a #{cfg.class}" unless Proc === cfg
- cfg
- end
- end
-
- def config! verb = @verb
- (@config ||= { })[verb] ||=
- begin
- save_verb = @verb
- @verb = verb
- $stderr.puts "#{log_str} calling #{config_rb} asir.verb=#{@verb.inspect} ..." if @verbose >= 1
- cfg = config_lambda.call(self)
- $stderr.puts "#{log_str} calling #{config_rb} asir.verb=#{@verb.inspect} DONE" if @verbose >= 1
- cfg
- ensure
- @verb = save_verb
- end
- end
-
- def pid_file
- "#{pid_dir}/#{asir_basename}.pid"
- end
-
- def log_file
- "#{log_dir}/#{asir_basename}.log"
- end
-
- def asir_basename
- "asir-#{adjective}-#{object}-#{identifier}"
- end
-
def fork_server! cmd = nil, &blk
pid = Process.fork do
run_server! cmd, &blk
end
log "forked pid #{pid}"
@@ -299,26 +273,26 @@
def _create_transport default_class
config!(:environment)
case transport = config!(:transport)
when default_class
- @transport = transport
+ self.transport = transport
else
raise "Expected config to return a #{default_class}, not a #{transport.class}"
end
end
def worker_pids
- (@worker_pids ||= { })[@adjective] ||= { }
+ (@worker_pids ||= { })[adjective] ||= { }
end
def _run_workers!
- $0 = "#{@progname} #{@adjective} #{@object} #{@identifier}"
+ $0 = "#{progname} #{adjective} #{object} #{identifier}"
worker_id = 0
- @transport.prepare_server!
- worker_processes = @transport[:worker_processes] || 1
+ transport.prepare_server!
+ worker_processes = transport[:worker_processes] || 1
(worker_processes - 1).times do
wid = worker_id += 1
pid = Process.fork do
_run_transport_server! wid
end
@@ -332,20 +306,20 @@
log "worker 0 stopped"
_stop_workers!
end
def _run_transport_server! wid = 0
- log "running transport worker #{@transport.class} #{wid}"
+ log "running transport worker #{transport.class} #{wid}"
config!(:start)
- $0 += " #{wid} #{@transport.uri rescue nil}"
+ $0 += " #{wid} #{transport.uri rescue nil}"
old_arg0 = $0.dup
- after_receive_message = @transport.after_receive_message || lambda { | transport, message | nil }
- @transport.after_receive_message = lambda do | transport, message |
+ after_receive_message = transport.after_receive_message || lambda { | transport, message | nil }
+ transport.after_receive_message = lambda do | transport, message |
$0 = "#{old_arg0} #{transport.message_count} #{message.identifier}"
after_receive_message.call(transport, message)
end
- @transport.run_server!
+ transport.run_server!
self
end
def _stop_workers!
workers = worker_pids.dup
@@ -366,11 +340,11 @@
log "stopping #{msg}pid #{pid}", :stderr
if process_running? pid
log "TERM pid #{pid}"
Process.kill('TERM', pid) rescue nil
sleep 3
- if @force or process_running? pid
+ if force or process_running? pid
log "KILL pid #{pid}", :stderr
Process.kill('KILL', pid) rescue nil
end
if process_running? pid
log "cant-stop pid #{pid}", :stderr
@@ -379,10 +353,17 @@
log "not-running? pid #{pid}", :stderr
end
end
def process_running? pid
- Process.kill(0, pid)
+ case pid
+ when false, nil
+ pid
+ when Integer
+ Process.kill(0, pid)
+ else
+ raise TypeError, "expected false, nil, Integer; given #{pid.inspect}"
+ end
true
rescue ::Errno::ESRCH
false
rescue ::Exception => exc
$stderr.puts " DEBUG: process_running? #{pid} => #{exc.inspect}"