1

我正在使用$ruby script_name命令运行以下脚本。父脚本生成两个子进程并等待 SIGTERM 或 SIGINT。父脚本能够按预期终止子进程。但是,在检查子日志时,我注意到退出期间记录了一个错误。是什么导致了这样的错误,我怎样才能避免它们干净地退出?

父/子脚本worker_monitor.rb

require 'rubygems'
require 'daemons'
require 'fileutils'

class SignalHandler
  attr_accessor :term

  def initialize(signal_str, name)
    @term = false
    Signal.trap(signal_str) do
      puts "#{name} #{signal_str} trapped"
      @term = true
    end
  end
end

cwd = Dir.pwd

options = {
  :multiple => true,
  :dir_mode => :normal,
  :dir => cwd,
  :backtrace => true,
  :log_output => true,
}

options1 = options.merge({ :log_dir => "#{cwd}/tmp/daemon/task1", :app_name => 'worker' })
FileUtils.mkdir_p("#{cwd}/tmp/daemon/task1")
task1 = Daemons.call(options1) do

  handler = SignalHandler.new("TERM", 'Task1')

  puts "Entered task1 (pid = #{Process.pid}, ppid = #{Process.ppid}), looping..."
  while !handler.term do
    puts "Task1 looped"
    sleep(5)
  end

  puts "Task1 stopped."
end

sleep(1) until task1.pid.running?()

puts "Check task1 status"
task1.show_status()


options2 = options.merge({ :log_dir => "#{cwd}/tmp/daemon/task2", :app_name => 'iamnotworker' })
FileUtils.mkdir_p("#{cwd}/tmp/daemon/task2")
task2 = Daemons.call(options2) do

  handler = SignalHandler.new("TERM", 'Task2')

  puts "Entered task2 (pid = #{Process.pid}, ppid = #{Process.ppid}), looping..."
  while !handler.term do
    puts "Task2 looped"
    sleep(5)
  end

  puts "Task2 stopped."
end

sleep(1) until task2.pid.running?()

puts "Check task2 status"
task2.show_status()


puts "Monitor (pid = #{Process.pid}) created children, looping ..."


handler_term = SignalHandler.new("TERM", 'Monitor')
handler_int = SignalHandler.new("INT", 'Monitor')


while !handler_term.term && !handler_int.term do
  sleep(5)
end

puts "Monitor exit loop."

puts "Stopping task1"
task1.stop()
puts "Stopping task2"
task2.stop()

sleep(1) while task1.pid.running?
sleep(1) while task2.pid.running?

sleep(2)

脚本标准输出:

Check task1 status
worker: running [pid 4977]
Check task2 status
worker: running [pid 4983]
Monitor (pid = 4972) created children, looping ...
Monitor TERM trapped
Monitor exit loop.
Stopping task1
worker: trying to stop process with pid 4977...
worker: process with pid 4977 successfully stopped.
Stopping task2
worker: trying to stop process with pid 4983...
worker: process with pid 4983 successfully stopped.

Task1 输出日志(Task2 有类似日志):

# Logfile created on 2013-06-24 22:26:55 -0700 by logger.rb/31641
I, [2013-06-24T22:26:55.281375 #4977]  INFO -- : *** below you find the most recent exception thrown, this will be likely (but not certainly) the exception that made the application exit abnormally ***
E, [2013-06-24T22:26:55.281533 #4977] ERROR -- : exit (SystemExit)
/home/user/.rvm/gems/ruby-1.9.3-p429/gems/daemons-1.1.9/lib/daemons/daemonize.rb:84:in `exit'
/home/user/.rvm/gems/ruby-1.9.3-p429/gems/daemons-1.1.9/lib/daemons/daemonize.rb:84:in `call_as_daemon'
/home/user/.rvm/gems/ruby-1.9.3-p429/gems/daemons-1.1.9/lib/daemons/application.rb:259:in `start_proc'
/home/user/.rvm/gems/ruby-1.9.3-p429/gems/daemons-1.1.9/lib/daemons/application.rb:296:in `start'
/home/user/.rvm/gems/ruby-1.9.3-p429/gems/daemons-1.1.9/lib/daemons.rb:252:in `call'
lib/worker_monitor.rb:29:in `<main>'
I, [2013-06-24T22:26:55.281754 #4977]  INFO -- : *** below you find all exception objects found in memory, some of them may have been thrown in your application, others may just be in memory because they are standard exceptions ***
E, [2013-06-24T22:26:55.283349 #4977] ERROR -- : stream closed (IOError)

E, [2013-06-24T22:26:55.283506 #4977] ERROR -- : failed to allocate memory (NoMemoryError)

E, [2013-06-24T22:26:55.283728 #4977] ERROR -- : stack level too deep (SystemStackError)

E, [2013-06-24T22:26:55.284156 #4977] ERROR -- : exception reentered (fatal)

E, [2013-06-24T22:26:55.284424 #4977] ERROR -- : exit (SystemExit)
/home/user/.rvm/gems/ruby-1.9.3-p429/gems/daemons-1.1.9/lib/daemons/daemonize.rb:84:in `exit'
/home/user/.rvm/gems/ruby-1.9.3-p429/gems/daemons-1.1.9/lib/daemons/daemonize.rb:84:in `call_as_daemon'
/home/user/.rvm/gems/ruby-1.9.3-p429/gems/daemons-1.1.9/lib/daemons/application.rb:259:in `start_proc'
/home/user/.rvm/gems/ruby-1.9.3-p429/gems/daemons-1.1.9/lib/daemons/application.rb:296:in `start'
/home/user/.rvm/gems/ruby-1.9.3-p429/gems/daemons-1.1.9/lib/daemons.rb:252:in `call'
lib/worker_monitor.rb:29:in `<main>'
4

1 回答 1

0

根据具体情况,也许类似的事情会有所帮助。

begin
  raise 'exception'
rescue Exception => e
  puts e.message
end

我建议您阅读一些关于异常的内容,因为很容易出错。

https://www.google.ro/search?q=ruby+exceptions+best+practices

于 2013-06-25T17:37:09.123 回答