Timeout error?

M

Mark Probert

Hi ..

I have the following code:


def alive?(host,port)
ok = false
begin
Timeout::timeout(30) {
begin
t = TCPSocket.new(host,port)
t.close
ok = true
rescue Exception => e
@exception = e
end
}
rescue Timeout::Error => e
@exception = e
end
return ok
end

In a known failure case, TCPSocket will fail (no host connectivity).
This will cause timeout() to trigger an exception that will get caught by
the Timeout::Error handler. Right?

However,

13:56 (hobbes)$ ruby foo.rb
Exception `Errno::ETIMEDOUT' at ./bsn.rb:150 - Connection timed out -

13:57 (hobbes)$ ruby -v
ruby 1.8.1 (2003-12-25) [i386-cygwin]

What is the right way of handling this exception?
 
B

Bill Atkins

Add a rescue clause for the exception you're getting:

begin
...
rescue Timeout::Error => e
...
rescue Errno::ETIMEDOUT => e
...
end

Is that what you're looking for?

Bill Atkins
 
M

Mark Probert

Hi ..

Bill Atkins said:
Add a rescue clause for the exception you're getting: ...
Is that what you're looking for?

Not quite.

I guess the real qustion is why Timeout::Error doesn't trap
Errno::ETIMEDOUT. The socket times out before the timeout() and raises a
different timeout error. Perhaps it would be better if, when a block is
wrapped in a Timeout::timeout, that all subservient timeouts should be
caught by the single rescue.

It does raise the question why the generic rescue isn't triggered.

Bill Atkins

Hi ..

I have the following code:

def alive?(host,port)
ok = false
begin
Timeout::timeout(30) {
begin
t = TCPSocket.new(host,port) # <--- line 150
t.close
ok = true
rescue Exception => e # why not caught here?
@exception = e
end
}
rescue Timeout::Error => e # or here?
@exception = e
end
return ok
end

In a known failure case, TCPSocket will fail (no host connectivity).

However,

13:56 (hobbes)$ ruby foo.rb
Exception `Errno::ETIMEDOUT' at ./bsn.rb:150 - Connection timed out -

13:57 (hobbes)$ ruby -v
ruby 1.8.1 (2003-12-25) [i386-cygwin]

What is the right way of handling this exception?
 
B

Bill Atkins

Hmm. Well, your rescue clause is looking specifically for exceptions
of type Timeout::Error or of a subclass of that class. Since
Errno::ETIMEDOUT isn't descended from Timeout::Error, the rescue
clause never gets called. If you want a generic rescue to catch
everything, try 'rescue Exception => e'

Bill

Hi ..

Bill Atkins said:
Add a rescue clause for the exception you're getting: ...
Is that what you're looking for?

Not quite.

I guess the real qustion is why Timeout::Error doesn't trap
Errno::ETIMEDOUT. The socket times out before the timeout() and raises a
different timeout error. Perhaps it would be better if, when a block is
wrapped in a Timeout::timeout, that all subservient timeouts should be
caught by the single rescue.

It does raise the question why the generic rescue isn't triggered.

Bill Atkins

Hi ..

I have the following code:

def alive?(host,port)
ok = false
begin
Timeout::timeout(30) {
begin
t = TCPSocket.new(host,port) # <--- line 150
t.close
ok = true
rescue Exception => e # why not caught here?
@exception = e
end
}
rescue Timeout::Error => e # or here?
@exception = e
end
return ok
end

In a known failure case, TCPSocket will fail (no host connectivity).

However,

13:56 (hobbes)$ ruby foo.rb
Exception `Errno::ETIMEDOUT' at ./bsn.rb:150 - Connection timed out -

13:57 (hobbes)$ ruby -v
ruby 1.8.1 (2003-12-25) [i386-cygwin]

What is the right way of handling this exception?
 
B

Brian Candler

I guess the real qustion is why Timeout::Error doesn't trap
Errno::ETIMEDOUT. The socket times out before the timeout() and raises a
different timeout error. Perhaps it would be better if, when a block is
wrapped in a Timeout::timeout, that all subservient timeouts should be
caught by the single rescue.

It does raise the question why the generic rescue isn't triggered.

It is for me (ruby-1.8.2p2, FreeBSD), so perhaps this is either a Windows
platform issue, or something from 1.8.1 which has been fixed.

$ cat foo.rb
require 'socket'
require 'timeout'

def alive?(host,port)
ok = false
begin
Timeout::timeout(30) {
begin
t = TCPSocket.new(host,port) # <--- line 150
t.close
ok = true
rescue Exception => e # why not caught here?
@exception = e
end
}
rescue Timeout::Error => e # or here?
@exception = e
end
return ok
end

p alive?('192.0.2.1',1234)
$ time ruby foo.rb
false

real 0m30.299s
user 0m0.076s
sys 0m0.024s

<< change timeout to 120 >>

$ time ruby foo.rb
false

real 1m15.155s
user 0m0.074s
sys 0m0.025s

(75 secs is the default TCP SYN timeout in FreeBSD)

Regards,

Brian.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top