I am trying to understand how signal handlers attach to a process and their scope for a process.
class Main
Signal.trap('USR1') do
Process2.kill
end
def main_process
#do something
p = Process2.new
output = p.give_output
#then again do something
end
end
class Process2
Signal.trap('USR1') do
Process2.kill
end
def self.kill
if ##static_object.blank?
#do nothing
else
#do something
end
end
def give_output
#do something
##static_object = true
#do something
end
end
Now if I issue a SIGUSR1 to the process while give_output is getting executed and ##static_object is not nil, the handler should behave as expected. However, even after give_output has finished execution, if a signal is sent, the handler inside Process2 will catch it. From what I understand, the handler gets attached to the process. Can we have two signal handlers for the same process for the same signal? For example - while give_output is executing and a signal is issued, the handler inside Process2 should get control otherwise another signal handler defined in Main should get control.
I was curious about this myself and came across the following resources: http://timuruski.net/blog/2014/signals-traps-and-rescues/, https://www.ruby-forum.com/topic/87221, and http://www.ibm.com/developerworks/library/l-reent/. That second link has some resources which seem very relevant to your question.
In short, you can only reliably trap one interrupt type per process. Signal interrupts are handled by the host OS. As its name suggests, interrupts halt the normal execution of your program until the interrupt is handled.
Summarizing the information given in the links posted by #Anthony E. Using signal trap it's not possible to trap a signal from multiple places in your code. If you want to handle signals differently at multiple places, use rescue blocks.
Signal Trap -
Signal.trap("USR1") do
#do something
end
Rescue Interrupt -
begin
#some functions
rescue Interrupt
#handle the exception
exit
end
Difference in the way signals are handled by rescue and trap -
Trap defines the handler at the top of the code, if a signal is triggered, it would be caught by the trap. On the other hand, rescue is defined at the bottom of the code, that is when there is no trap available, it will raise a Signal Exception which will be caught by the rescue block
The signal trap code gets associated with the process and cannot be replaced. If one wants to handle signals at different places of the program in a different way, the best way is to raise an exception and handle it
I'm using Bunny gem for consuming messages via AMQP. My app is subscribed for messages in a queue, it's a neverending blocking call (via subscribe block). I'd like it to shut down gracefully while the process is interrupted (e.g. ctrl+c in terminal). What's the proper way to do it? I would like it to process the current message if it's processing one and then jump out of the block.
code example:
trap("INT") do
puts "Stopping now"
Indexer.client.stop # ???
end
module Indexer
extend self
def run
client.queue('indexer.index').subscribe do |msg|
# omitted
end
end
def client
#client ||= Bunny.new.tap(&:start)
end
end
Indexer.run # runs forever
I know this question is 2 years old, and you've probably figured out something by now. That said, the way I'd handle this would be to put a 'should I quit?' check at the end of your subscribe loop, and then have your SIGINT trap toggle the variable. Bunny itself is pretty good about cleaning up all the AMQP connection stuff, so you really would only need to worry about your own bits on exiting.
Ryan Davis’s Ruby QuickRef says (without explanation):
Don’t rescue Exception. EVER. or I will stab you.
Why not? What’s the right thing to do?
TL;DR: Use StandardError instead for general exception catching. When the original exception is re-raised (e.g. when rescuing to log the exception only), rescuing Exception is probably okay.
Exception is the root of Ruby's exception hierarchy, so when you rescue Exception you rescue from everything, including subclasses such as SyntaxError, LoadError, and Interrupt.
Rescuing Interrupt prevents the user from using CTRLC to exit the program.
Rescuing SignalException prevents the program from responding correctly to signals. It will be unkillable except by kill -9.
Rescuing SyntaxError means that evals that fail will do so silently.
All of these can be shown by running this program, and trying to CTRLC or kill it:
loop do
begin
sleep 1
eval "djsakru3924r9eiuorwju3498 += 5u84fior8u8t4ruyf8ihiure"
rescue Exception
puts "I refuse to fail or be stopped!"
end
end
Rescuing from Exception isn't even the default. Doing
begin
# iceberg!
rescue
# lifeboats
end
does not rescue from Exception, it rescues from StandardError. You should generally specify something more specific than the default StandardError, but rescuing from Exception broadens the scope rather than narrowing it, and can have catastrophic results and make bug-hunting extremely difficult.
If you have a situation where you do want to rescue from StandardError and you need a variable with the exception, you can use this form:
begin
# iceberg!
rescue => e
# lifeboats
end
which is equivalent to:
begin
# iceberg!
rescue StandardError => e
# lifeboats
end
One of the few common cases where it’s sane to rescue from Exception is for logging/reporting purposes, in which case you should immediately re-raise the exception:
begin
# iceberg?
rescue Exception => e
# do some logging
raise # not enough lifeboats ;)
end
The real rule is: Don't throw away exceptions. The objectivity of the author of your quote is questionable, as evidenced by the fact that it ends with
or I will stab you
Of course, be aware that signals (by default) throw exceptions, and normally long-running processes are terminated through a signal, so catching Exception and not terminating on signal exceptions will make your program very hard to stop. So don't do this:
#! /usr/bin/ruby
while true do
begin
line = STDIN.gets
# heavy processing
rescue Exception => e
puts "caught exception #{e}! ohnoes!"
end
end
No, really, don't do it. Don't even run that to see if it works.
However, say you have a threaded server and you want all exceptions to not:
be ignored (the default)
stop the server (which happens if you say thread.abort_on_exception = true).
Then this is perfectly acceptable in your connection handling thread:
begin
# do stuff
rescue Exception => e
myLogger.error("uncaught #{e} exception while handling connection: #{e.message}")
myLogger.error("Stack trace: #{backtrace.map {|l| " #{l}\n"}.join}")
end
The above works out to a variation of Ruby's default exception handler, with the advantage that it doesn't also kill your program. Rails does this in its request handler.
Signal exceptions are raised in the main thread. Background threads won't get them, so there is no point in trying to catch them there.
This is particularly useful in a production environment, where you do not want your program to simply stop whenever something goes wrong. Then you can take the stack dumps in your logs and add to your code to deal with specific exception further down the call chain and in a more graceful manner.
Note also that there is another Ruby idiom which has much the same effect:
a = do_something rescue "something else"
In this line, if do_something raises an exception, it is caught by Ruby, thrown away, and a is assigned "something else".
Generally, don't do that, except in special cases where you know you don't need to worry. One example:
debugger rescue nil
The debugger function is a rather nice way to set a breakpoint in your code, but if running outside a debugger, and Rails, it raises an exception. Now theoretically you shouldn't be leaving debug code lying around in your program (pff! nobody does that!) but you might want to keep it there for a while for some reason, but not continually run your debugger.
Note:
If you've run someone else's program that catches signal exceptions and ignores them, (say the code above) then:
in Linux, in a shell, type pgrep ruby, or ps | grep ruby, look for your offending program's PID, and then run kill -9 <PID>.
in Windows, use the Task Manager (CTRL-SHIFT-ESC), go to the "processes" tab, find your process, right click it and select "End process".
If you are working with someone else's program which is, for whatever reason, peppered with these ignore-exception blocks, then putting this at the top of the mainline is one possible cop-out:
%W/INT QUIT TERM/.each { |sig| trap sig,"SYSTEM_DEFAULT" }
This causes the program to respond to the normal termination signals by immediately terminating, bypassing exception handlers, with no cleanup. So it could cause data loss or similar. Be careful!
If you need to do this:
begin
do_something
rescue Exception => e
critical_cleanup
raise
end
you can actually do this:
begin
do_something
ensure
critical_cleanup
end
In the second case, critical cleanup will be called every time, whether or not an exception is thrown.
TL;DR
Don't rescue Exception => e (and not re-raise the exception) - or you might drive off a bridge.
Let's say you are in a car (running Ruby). You recently installed a new steering wheel with the over-the-air upgrade system (which uses eval), but you didn't know one of the programmers messed up on syntax.
You are on a bridge, and realize you are going a bit towards the railing, so you turn left.
def turn_left
self.turn left:
end
oops! That's probably Not Good™, luckily, Ruby raises a SyntaxError.
The car should stop immediately - right?
Nope.
begin
#...
eval self.steering_wheel
#...
rescue Exception => e
self.beep
self.log "Caught #{e}.", :warn
self.log "Logged Error - Continuing Process.", :info
end
beep beep
Warning: Caught SyntaxError Exception.
Info: Logged Error - Continuing Process.
You notice something is wrong, and you slam on the emergency breaks (^C: Interrupt)
beep beep
Warning: Caught Interrupt Exception.
Info: Logged Error - Continuing Process.
Yeah - that didn't help much. You're pretty close to the rail, so you put the car in park (killing: SignalException).
beep beep
Warning: Caught SignalException Exception.
Info: Logged Error - Continuing Process.
At the last second, you pull out the keys (kill -9), and the car stops, you slam forward into the steering wheel (the airbag can't inflate because you didn't gracefully stop the program - you terminated it), and the computer in the back of your car slams into the seat in front of it. A half-full can of Coke spills over the papers. The groceries in the back are crushed, and most are covered in egg yolk and milk. The car needs serious repair and cleaning. (Data Loss)
Hopefully you have insurance (Backups). Oh yeah - because the airbag didn't inflate, you're probably hurt (getting fired, etc).
But wait! There's more reasons why you might want to use rescue Exception => e!
Let's say you're that car, and you want to make sure the airbag inflates if the car is exceeding its safe stopping momentum.
begin
# do driving stuff
rescue Exception => e
self.airbags.inflate if self.exceeding_safe_stopping_momentum?
raise
end
Here's the exception to the rule: You can catch Exception only if you re-raise the exception. So, a better rule is to never swallow Exception, and always re-raise the error.
But adding rescue is both easy to forget in a language like Ruby, and putting a rescue statement right before re-raising an issue feels a little non-DRY. And you do not want to forget the raise statement. And if you do, good luck trying to find that error.
Thankfully, Ruby is awesome, you can just use the ensure keyword, which makes sure the code runs. The ensure keyword will run the code no matter what - if an exception is thrown, if one isn't, the only exception being if the world ends (or other unlikely events).
begin
# do driving stuff
ensure
self.airbags.inflate if self.exceeding_safe_stopping_momentum?
end
Boom! And that code should run anyways. The only reason you should use rescue Exception => e is if you need access to the exception, or if you only want code to run on an exception. And remember to re-raise the error. Every time.
Note: As #Niall pointed out, ensure always runs. This is good because sometimes your program can lie to you and not throw exceptions, even when issues occur. With critical tasks, like inflating airbags, you need to make sure it happens no matter what. Because of this, checking every time the car stops, whether an exception is thrown or not, is a good idea. Even though inflating airbags is a bit of an uncommon task in most programming contexts, this is actually pretty common with most cleanup tasks.
Because this captures all exceptions. It's unlikely that your program can recover from any of them.
You should handle only exceptions that you know how to recover from. If you don't anticipate a certain kind of exception, don't handle it, crash loudly (write details to the log), then diagnose logs and fix code.
Swallowing exceptions is bad, don't do this.
That's a specific case of the rule that you shouldn't catch any exception you don't know how to handle. If you don't know how to handle it, it's always better to let some other part of the system catch and handle it.
This blog post explains it perfectly:
Ruby's Exception vs StandardError: What's the difference?
Why you shouldn't rescue Exception
The problem with rescuing Exception
is that it actually rescues every exception that inherits from
Exception. Which is....all of them!
That's a problem because there are some exceptions that are used
internally by Ruby. They don't have anything to do with your app, and
swallowing them will cause bad things to happen.
Here are a few of the big ones:
SignalException::Interrupt - If you rescue this, you can't exit your
app by hitting control-c.
ScriptError::SyntaxError - Swallowing syntax errors means that things
like puts("Forgot something) will fail silently.
NoMemoryError - Wanna know what happens when your program keeps
running after it uses up all the RAM? Me neither.
begin
do_something()
rescue Exception => e
# Don't do this. This will swallow every single exception. Nothing gets past it.
end
I'm guessing that you don't really want to swallow any of these
system-level exceptions. You only want to catch all of your
application level errors. The exceptions caused YOUR code.
Luckily, there's an easy way to to this.
Rescue StandardError Instead
All of the exceptions that you should care about inherit from StandardError. These are our old friends:
NoMethodError - raised when you try to invoke a method that doesn't exist
TypeError - caused by things like 1 + ""
RuntimeError - who could forget good old RuntimeError?
To rescue errors like these, you'll want to rescue StandardError. You COULD do it by writing something like this:
begin
do_something()
rescue StandardError => e
# Only your app's exceptions are swallowed. Things like SyntaxErrror are left alone.
end
But Ruby has made it much easier for use.
When you don't specify an exception class at all, ruby assumes you mean StandardError. So the code below is identical to the above code:
begin
do_something()
rescue => e
# This is the same as rescuing StandardError
end
I'm implementing a ruby server for handling sockets being created from GPRS modules. The thing is that when the module powers down, there's no indication that the socket closed.
I'm doing threads to handle multiple sockets with the same server. What I'm asking is this: Is there a way to use a timer inside a thread, reset it after every socket input, and that if it hits the timeout, closes the thread? Where can I find more information about this?
EDIT: Code example that doesn't detect the socket closing
require 'socket'
server = TCPServer.open(41000)
loop do
Thread.start(server.accept) do |client|
puts "Client connected"
begin
loop do
line = client.readline
open('log.txt', 'a') { |f|
f.puts line.strip
}
end
rescue
puts "Client disconnected"
end
end
end
I think you need a heartbeat mechanism.
At a guess, your sockets are inexplably closing because you're not catching exceptions that are raised when they are closed by the remote end.
you need to wrap the connection handler in an exception catching block.
Without knowing what module/model you're using I will just fudge it and say you have a process_connection routine. So you need to do something like this:
def process_connection(conn)
begin
# do stuff
rescue Exception => e
STDERR.print "Caught exception #{e}: #{e.message}\n#{e.backtrace}\n"
ensure
conn.close
end
end
This will catch all exceptions and dump them to stderr with a stack trace. From there you can see what is causing them, and possibly handle them more gracefully elsewhere.
Just check the standar API Timeout:
require 'timeout'
status = Timeout::timeout(3){sleep(1)}
puts status.inspect
status = Timeout::timeout(1){sleep(2)}
I'm looking for a portable interface to POSIX alarm(2) (or similar) in Ruby. That's to say, I would like to be able to set a background timer to send a signal to the current process after n seconds.
I have found some good discussion from 2006 on the ruby-talk list that provides a solution using dl/import, but that's a bit of a hack (albeit a neat hack) and not very portable.
I've looked at the much-maligned Timeout module and that won't cut it under JRuby although it works fine with the traditional interpreter. My program is a small command-line shell that uses the Readline library:
TIMEOUT = 5 # seconds
loop do
input = nil
begin
Timeout.timeout(TIMEOUT) do
input = Readline::readline('> ', nil)
end
rescue Timeout::Error
puts "Timeout"
next
end
# do something with input
end
Under JRuby it seems the process blocks in the readline call and Timeout::Error is only thrown after (a) the timer expires and (b) the user enters a new line. And the exception doesn't get rescued. Hmm.
So I came up with this workaround:
require 'readline'
class TimeoutException < Exception ; end
TIMEOUT = 5 # seconds
loop do
input = nil
start_time = Time.now
thread = Thread.new { input = Readline::readline('> ', nil) }
begin
while thread.alive? do
sleep(1) # prevent CPU from melting
raise TimeoutException if(Time.now - start_time > TIMEOUT)
end
rescue TimeoutException
thread.exit
puts "Timeout"
end
# do something with input
end
This is... clunky (let's be polite). I just want alarm(2)! I don't really want to drag in non-core libraries (eg Terminator) for this. Is there a better way?
EDIT:
I can't get another alternative -- creating a thread that sleeps and then sends a signal to the process -- to work under JRuby either. Does JRuby eat signals? Example:
SIG = 'USR2'
Signal.trap(SIG) { raise }
Process.kill(SIG, Process.pid)
JRuby simply returns, Ruby returns the expected "unhandled exception" error.
I'm sorry that I don't have an answer to your larger problem of sending a signal after X seconds to a process, but it seems that all you want to do is timeout after X seconds of waiting for input, and if that's the case then I'd say you are looking for Kernel.select :D
I've personally never used this, but after doing a google for "non-blocking gets", and subsequently exploring links, I found these two to be invaluable discussions:
http://www.ruby-forum.com/topic/126795 (Discussion of multi-threaded gets)
http://www.ruby-forum.com/topic/121404 (Explanation of Kernel.select in 2nd post)
Here's a sample of how to use it. This will print out your prompt and wait for input... If there is no input after five seconds, then the program will end. If there is input, as soon as there is input it will spit it back out and end... Obviously you can modify this for your own purposes.
def prompt
STDOUT.write "> "
STDOUT.flush
end
def amusing_messages
[ "You must enter something!",
"Why did you even start me if you just wanted to stare at me?",
"Isn't there anything better you could be doing?",
"Just terminate me already... this is getting old",
"I'm waiting..."]
end
prompt
loop do
read_array, write_array, error_array = Kernel.select [STDIN], nil, nil, 5
if read_array.nil?
puts amusing_messages[rand(amusing_messages.length)]
else
puts "Result is: #{read_array[0].read_nonblock(30)}"
end
prompt
end
It's probably not as elegant as you might like, but it definitely gets the job done without mucking around with threads. Unfortunately, this won't help you should you want something more robust (timer/sending a signal to the process), and sadly, I have no clue if this works in JRuby. Would love to know if it does though :)