Hi,
I'm having trouble catching the exception raised by Timeout.timeout
Using the following code:
require 'timeout'
begin
Timeout::timeout(1) do
sleep(5)
end
rescue
puts "rescued in outer"
end
The interpreter stops with the following:
/usr/lib/ruby/1.8/timeout.rb:54: execution expired (Timeout::Error)
from /usr/lib/ruby/1.8/timeout.rb:56:in `timeout'
from test.rb:21
I can't catch the exception from within the block, either:
require 'timeout'
Timeout::timeout(1) do
begin
sleep(5)
rescue
puts "rescued in inner"
end
end
This gives the same error:
/usr/lib/ruby/1.8/timeout.rb:54: execution expired (Timeout::Error)
from /usr/lib/ruby/1.8/timeout.rb:56:in `timeout'
from test2.rb:8
Is this a known problem, or am I using Timeout incorrectly?
I am using a workaround for now -- my own implementation:
module TimeLimit
class Expired < RuntimeError; end
def self.timeout(sec, &block)
worker = Thread.new(&block)
killer = Thread.new { sleep sec; worker.raise Expired.new if
worker.alive? }
worker.join
killer.kill if killer.alive?
end
end
With the above code, the following prints 'expired' followed by
'finished', as I would expect:
TimeLimit::timeout(1) do
begin
sleep 5
puts "finished"
rescue TimeLimit::Expired
puts "expired"
end
end
TimeLimit::timeout(5) do
begin
sleep 1
puts "finished"
rescue TimeLimit::Expired
puts "expired"
end
end
Cheers,
Rik