On Jan 23, 2007, at 20:22, Daniel Martin wrote:
> Looking at that, and at other messages in this thread, I tried this
> experiment.  First, I set up a service locally that listened to port
> 8989 and simply echoed ten lines with a five second delay between each
> echo.  (with a simple shell script + inetd)
>
> Then, in irb:
>
> require "socket"
> (1..1300).map{|s|puts s;a=TCPSocket.open("localhost", 
> 8989);a.readline;a}
>
> This fails with the same EOFError reported in ftp.rb, after opening
> the 256th socket.  (I use "map" instead of "each" to keep from closing
> sockets in garbage collection)

$ cat test.rb
soft, hard = Process.getrlimit Process::RLIMIT_NOFILE
require 'socket'

sockets = (1..soft).map do |n|
   s = TCPSocket.open "localhost", 80
   s.write "GET / HTTP/1.0\r\n\r\n"
   print "%4d %s" % [n, s.readline]
   s
end

p sockets

$ ruby test.rb
    1 HTTP/1.1 200 OK
[...]
  252 HTTP/1.1 200 OK
test.rb:5:in `initialize': Too many open files - socket(2)  
(Errno::EMFILE)
         from test.rb:5:in `open'
         from test.rb:5
         from test.rb:2:in `map'
         from test.rb:4:in `each'
         from test.rb:4:in `map'
         from test.rb:4

> It would seem that somehow when the underlying operating system has
> too many descriptors open, the effect is that TCPSocket.open succeeds,
> but it manages to succeed in such a manner that .readline on the
> resulting socket will immediately trigger EOFError.

$ ruby -v
ruby 1.8.5 (2006-12-04 patchlevel 2) [i686-darwin8.8.2]

> Looking at ext/socket.c, I don't see how that's possible.  The
> socket() call should be returning -1 (with errno set to ENFILE) which
> should cause init_inetsock_internal to invoke
> rb_sys_fail("socket(2)"), but clearly that isn't happening.
>
> So:
>
> ftp.rb gives this error message when there are too many connections
> open in this process.  The fault seems to be that TCPSocket.open
> claims to succeed when it didn't really.  It is a mystery why that
> happens.



-- 
Eric Hodel - drbrain / segment7.net - http://blog.segment7.net

I LIT YOUR GEM ON FIRE!