def call_action(action)
command = send(action)
if action == :stop && command.nil?
pid = self.pid
name = self.name
command = lambda do
applog(self, :info, "#{self.name} stop: default lambda killer")
::Process.kill(@stop_signal, pid) rescue nil
applog(self, :info, "#{self.name} sent SIG#{@stop_signal}")
@stop_timeout.times do
begin
::Process.kill(0, pid)
rescue Errno::ESRCH
applog(self, :info, "#{self.name} process stopped")
return
end
sleep 1
end
::Process.kill('KILL', pid) rescue nil
applog(self, :warn, "#{self.name} still alive after #{@stop_timeout}s; sent SIGKILL")
end
end
if command.kind_of?(String)
pid = nil
if [:start, :restart].include?(action) && @tracking_pid
r, w = IO.pipe
begin
opid = fork do
STDOUT.reopen(w)
r.close
pid = self.spawn(command)
puts pid.to_s
end
::Process.waitpid(opid, 0)
w.close
pid = r.gets.chomp
ensure
r.close rescue nil
w.close rescue nil
end
else
pid = self.spawn(command)
status = ::Process.waitpid2(pid, 0)
exit_code = status[1] >> 8
if exit_code != 0
applog(self, :warn, "#{self.name} #{action} command exited with non-zero code = #{exit_code}")
end
ensure_stop if action == :stop
end
if @tracking_pid or (@pid_file.nil? and WRITES_PID.include?(action))
File.open(default_pid_file, 'w') do |f|
f.write pid
end
@tracking_pid = true
@pid_file = default_pid_file
end
elsif command.kind_of?(Proc)
command.call
else
raise NotImplementedError
end
end