[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Timeout error?

Mark Probert

10/4/2004 9:08:00 PM


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?

--
-mark. (probertm @ acm dot org)

4 Answers

Bill Atkins

10/5/2004 1:21:00 AM

0

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

On Tue, 5 Oct 2004 06:09:53 +0900, Mark Probert <probertm@nospam-acm.org> wrote:
>
> 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?
>
> --
> -mark. (probertm @ acm dot org)
>
>


Mark Probert

10/5/2004 5:03:00 AM

0

Hi ..

Bill Atkins <batkins57@gmail.com> wrote:
>
> 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
>
> On Tue, 5 Oct 2004 06:09:53 +0900, Mark Probert
> <probertm@nospam-acm.org> wrote:
>>
>> 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?
>>
>> --
>> -mark. (probertm @ acm dot org)
>>
>>
>
>
>



--
-mark. (probertm @ acm dot org)

Bill Atkins

10/5/2004 5:20:00 AM

0

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

On Tue, 5 Oct 2004 14:04:53 +0900, Mark Probert <probertm@nospam-acm.org> wrote:
> Hi ..
>
> Bill Atkins <batkins57@gmail.com> wrote:
> >
> > 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
> >
> > On Tue, 5 Oct 2004 06:09:53 +0900, Mark Probert
> > <probertm@nospam-acm.org> wrote:
> >>
> >> 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?
> >>
> >> --
> >> -mark. (probertm @ acm dot org)
> >>
> >>
> >
> >
> >
>
>
>
>
> --
> -mark. (probertm @ acm dot org)
>
>


Brian Candler

10/6/2004 11:36:00 AM

0

On Tue, Oct 05, 2004 at 02:04:53PM +0900, Mark Probert wrote:
> 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.