Prev: change gem user agent
Next: awesome-cli-ruby
From: Robert Klemme on 21 Jun 2010 07:27 2010/6/21 Martin Hansen <mail(a)maasha.dk>: > Hm, I am not making myself clear :o( - Apparently. > It is the status of the ruby > script at hand I want to log. $? is probably barking up the wrong tree > and adding confusion. In Perl I would do this trapping the signal. > >> trap in your Ruby script will trap signals for this process not the >> forked process - unless you use the block form of fork in which case I >> believe the child inherits all signal handlers. > > #!/usr/bin/env ruby > > signal = nil > > trap("INT") { signal = "interupted"; exit } > #trap("TERM") { signal = "terminated"; exit } > > at_exit { puts "Put this in logfile: #{signal}" } IMHO it's bad practice to simply exit from a signal handler because you do not know what the application currently does. It is less dramatic in Ruby because exit really throws an exception in the interrupted thread: $ ruby19 -e 'trap("INT"){ puts "int"; exit 1 }; begin; sleep 20; rescue Exception => e; p e; end' int #<SystemExit: exit> $ But if you have multiple active threads they are not properly cleaned up: $ ruby19 -e 'trap("INT"){ puts "INT #{Thread.current}"; exit 1 }; 2.times { Thread.new { begin; sleep 20; rescue Exception => e; p e; ensure p Thread.current; end } }; sleep 30' INT #<Thread:0x1004e2a4> #<Thread:0x10042a90 run> #<Thread:0x10042978 run> $ Notice how all three threads are terminated but the two background threads obviously do not see an exception. In this case it is generally better to somehow globally communicate that the process is asked to shut down so all parties can properly end their business. > sleep 5 > > I have two issues with this: I loose the stack trace that is normally > printed to stderr (I still want that printed to stderr): > > ./test.rb:10:in `sleep': Interrupt > from ./test.rb:10:in `<main>' > > > And I fail setting signal as a global variable (if that can be done?) so > I can use it from within a class without getting errors like this: > > in `block in <class:Biopieces>': undefined local variable or method > `signal' for Biopieces:Class (NameError) It seems there is a much simpler solution to what you want - you don't even need a signal handler for this: $ ruby19 -e 'begin; sleep 60; rescue Exception => e; p e.class, e, e.backtrace; end' & [1] 2664 $ echo $! 2664 $ kill -INT $! $ Interrupt Interrupt ["-e:1:in `sleep'", "-e:1:in `<main>'"] [1]+ Done ruby19 -e 'begin; sleep 60; rescue Exception => e; p e.class, e, e.backtrace; end' $ Cheers robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/
From: Martin Hansen on 21 Jun 2010 08:48
> It seems there is a much simpler solution to what you want - you don't > even need a signal handler for this: > > $ ruby19 -e 'begin; sleep 60; rescue Exception => e; p e.class, e, > e.backtrace; end' & > [1] 2664 > $ echo $! > 2664 > $ kill -INT $! > $ Interrupt > Interrupt > ["-e:1:in `sleep'", "-e:1:in `<main>'"] > [1]+ Done ruby19 -e 'begin; sleep 60; rescue > Exception => e; p e.class, e, e.backtrace; end' > That indeed looks very clever. But I note that if the script is terminated I get "SignalException" and not "Terminated". Also, I note that backtrace is a list, and I was wondering what method Ruby normally uses to reformat and pretty print that (Ruby is not simply printing and indenting the lines). However, I fail to see how this exception handling should be integrated in practice with my code that currently relies on an at_exit call (line 84): http://code.google.com/p/biopieces/source/browse/trunk/code_ruby/Maasha/lib/biopieces.rb And just a reminder that I am trying to create super simplified scripts of this type: http://pastie.org/1013476 Cheers, Martin -- Posted via http://www.ruby-forum.com/. |