From: Eric Hodel Date: 2007-01-24T16:24:00+09:00 Subject: Re: Does Ruby's FTP lib have a ghostly bug? 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!