Ruby Timeout::timeout doesn't fire Exception and doesn't return what documented
Asked Answered
B

3

10

I have this piece of code:

begin
  complete_results = Timeout.timeout(4) do      
    results = platform.search(artist, album_name)
  end
rescue Timeout::Error
  puts 'Print me something please'
end 

I then launch the method containing this code, and well, here is the beginning of a stack trace:

Exception message :  execution expired
Exception backtrace :  /***/****/.rvm/rubies/ruby-1.8.7-p302/lib/ruby/1.8/timeout.rb:64:i

So I naively thinks that my call timed out, but 'Print me something please' is never printed and complete_results which is suppose to be the timeout status return value (either true or false, as mentioned in the documentation), is definitively not a boolean.

Am I doing something wrong?

Beggary answered 9/1, 2011 at 2:4 Comment(0)
N
21

Your code is correct

require 'timeout'
begin
  complete_results = Timeout.timeout(1) do      
   sleep(2)
  end
rescue Timeout::Error
  puts 'Print me something please'
end

does print out "print me something please".

Try the basic code as above. If that works, you have an issue in platform.search.

Nisi answered 9/1, 2011 at 2:33 Comment(1)
You were definitively right. I Don't know why i didn't check platform.search. Actually, search was rescueing.. Exception... Thank's a lot!Beggary
P
5

The problem is that platform.search is catching the exception that Timeout#timeout throws.

You can get around this by wrapping your inner code in another thread -- YMMV.

begin
  complete_results = Timeout.timeout(4) do
    Thread.new{ results = platform.search(artist, album_name) }.value
  end
rescue Timeout::Error
  puts 'Print me something please'
end 
Plexiform answered 14/5, 2012 at 13:18 Comment(3)
I recently described and, possibly, fixed this problem, here: code.jjb.cc/2012/09/15/…Plexiform
Timeout does suck, but this Threaded approach works well, thanksTempt
or try soft_timeout https://github.com/abhi-patel/soft_timeoutCidevant
C
1

According to the documentation:

If the block execution terminates before sec seconds has passed, it returns true. If not, it terminates the execution and raises exception (which defaults to Timeout::Error)

This means it only returns true if it's successful, otherwise the variable will not be set (ie it's nil NOT false).

As far as your example goes, it's definitely timing out for me and getting to the rescue part...

Chinese answered 9/1, 2011 at 2:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.