2013-06-25 7 views
1

Я запускаю следующий скрипт с командой $ruby script_name. Родительский скрипт порождает два дочерних процесса и ждет SIGTERM или SIGINT. Родительский скрипт способен прерывать дочерние процессы, как ожидалось. Однако при проверке дочернего журнала я заметил, что во время выхода была зарегистрирована ошибка. Что вызывает такую ​​ошибку и как я могу избежать их выхода из строя?Ruby Daemon gem как избежать ошибок выхода?

Parent/Child Script 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) 

Script STDOUT:

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>' 

ответ

0

В зависимости от случая, возможно, что-то подобное этому может помочь.

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

Я рекомендую вам немного прочитать об исключениях, так как легко ошибаться.

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

+0

Итак, как вы предлагаете, чтобы завершить дочерний процесс при ловле на 'SystemExit' исключения из дочернего процесса, когда' вызов exit' функции в 'daemons' библиотеки драгоценных камней? – devil