[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Puzzled about Ruby's behaviour re. closed sockets

Emmanuel Gaillot

7/29/2007 3:04:00 PM

Everyone,

I'd like to write a test that ensures a Server application correctly
handles closed client connections -- more specifically: I want to set
up a TCPServer, then a client, then close the client, then attempt to
write on the client Connection from server side -- and make sure no
Error gets fired.

To my great surprise, the test doesn't behave in any predictible way
-- sometimes it passes, sometimes it fails.

I've written a piece of code that illustrates it:
=============
require 'socket'

consecutive_puts_to_attempt = 1
ok_counter = 0
error_counter = 0

10000.times do
server = TCPServer.open '127.0.0.1', 4807
client = TCPSocket.open '127.0.0.1', 4807
connection = server.accept
client.close

begin
consecutive_puts_to_attempt.times {connection.puts "Hello!"}
ok_counter += 1
rescue
error_counter += 1
end
server.close
end

puts "(Unexpectedly) passed #{ok_counter} times;"
puts "(correctly) failed #{error_counter} times."
=============

Statistically, this piece of code unexpectedly passes with no raised
error about 98% of the time. Errors are Errno::EPIPE and
Errno::ECONNRESET

When I fiddle with consecutive_puts_to_attempt value, the number of
expected raised errors changes --

puts attempts chances of raised error
1 2%
2 98%
3 98.5%
4 99%


Here is my environment:
ruby -v
> ruby 1.8.6 (2007-03-13 patchlevel 0) [i686-darwin8.10.1]

Any idea of what's going on?
Any suggestion about how I could make this piece of code predictible?
-- Emmanuel.

2 Answers

Robert Klemme

7/30/2007 7:58:00 AM

0

2007/7/29, Emmanuel Gaillot <emmanuel.gaillot@gmail.com>:
> I'd like to write a test that ensures a Server application correctly
> handles closed client connections -- more specifically: I want to set
> up a TCPServer, then a client, then close the client, then attempt to
> write on the client Connection from server side -- and make sure no
> Error gets fired.
>
> To my great surprise, the test doesn't behave in any predictible way
> -- sometimes it passes, sometimes it fails.

> Any idea of what's going on?
> Any suggestion about how I could make this piece of code predictible?

I guess it's a combination of timing and buffering issue. With a
modified version I get

RKlemme@padrklemme1 ~
$ ruby ruby/socket-test-1.rb
(Unexpectedly) passed 2 times;
{Errno::ECONNABORTED=>998}

(see attachment)

Kind regards

robert

Emmanuel Gaillot

7/31/2007 9:22:00 AM

0

Robert,

Thanks for your answer.

> With a modified version I get
>
> (Unexpectedly) passed 2 times;
> {Errno::ECONNABORTED=>998}

I've tried your modified version. Here is a typical output when
attempting once to write in the closed pipe :
----------------------------------------------
(Unexpectedly) passed 960 times;
{Errno::EPIPE=>38, Errno::ECONNRESET=>2}
----------------------------------------------

.... this to be compared with typical output when attempting to write
6th times in a row in the closed pipe :
----------------------------------------------
(Unexpectedly) passed 4 times;
{Errno::EPIPE=>987, Errno::ECONNRESET=>9}
----------------------------------------------

Strangely enough, I don't seem to get any Errno::ECONNABORTED ever.


> I guess it's a combination of timing and buffering issue.

I've reached the same conclusion -- which brings me to the question:
what can I do to make the combination of timing and buffering
predictible? Or how may I get around it?

-- Emmanuel.