THRIFT-3641 Ruby client should try to connect to every result of getaddrinfo
Client: Ruby
Patch: Nobuaki Sukegawa

This closes #872
diff --git a/lib/rb/lib/thrift/transport/socket.rb b/lib/rb/lib/thrift/transport/socket.rb
index 2b7ca09..517d112 100644
--- a/lib/rb/lib/thrift/transport/socket.rb
+++ b/lib/rb/lib/thrift/transport/socket.rb
@@ -33,26 +33,28 @@
     attr_accessor :handle, :timeout
 
     def open
-      begin
-        addrinfo = ::Socket::getaddrinfo(@host, @port, nil, ::Socket::SOCK_STREAM).first
-        @handle = ::Socket.new(addrinfo[4], ::Socket::SOCK_STREAM, 0)
-        @handle.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, 1)
-        sockaddr = ::Socket.sockaddr_in(addrinfo[1], addrinfo[3])
+      for addrinfo in ::Socket::getaddrinfo(@host, @port, nil, ::Socket::SOCK_STREAM) do
         begin
-          @handle.connect_nonblock(sockaddr)
-        rescue Errno::EINPROGRESS
-          unless IO.select(nil, [ @handle ], nil, @timeout)
-            raise TransportException.new(TransportException::NOT_OPEN, "Connection timeout to #{@desc}")
-          end
+          socket = ::Socket.new(addrinfo[4], ::Socket::SOCK_STREAM, 0)
+          socket.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, 1)
+          sockaddr = ::Socket.sockaddr_in(addrinfo[1], addrinfo[3])
           begin
-            @handle.connect_nonblock(sockaddr)
-          rescue Errno::EISCONN
+            socket.connect_nonblock(sockaddr)
+          rescue Errno::EINPROGRESS
+            unless IO.select(nil, [ socket ], nil, @timeout)
+              next
+            end
+            begin
+              socket.connect_nonblock(sockaddr)
+            rescue Errno::EISCONN
+            end
           end
+          return @handle = socket
+        rescue StandardError => e
+          next
         end
-        @handle
-      rescue StandardError => e
-        raise TransportException.new(TransportException::NOT_OPEN, "Could not connect to #{@desc}: #{e}")
       end
+      raise TransportException.new(TransportException::NOT_OPEN, "Could not connect to #{@desc}: #{e}")
     end
 
     def open?
diff --git a/lib/rb/spec/socket_spec.rb b/lib/rb/spec/socket_spec.rb
index e6b6732..8e1ef50 100644
--- a/lib/rb/spec/socket_spec.rb
+++ b/lib/rb/spec/socket_spec.rb
@@ -35,7 +35,7 @@
     it_should_behave_like "a socket"
 
     it "should raise a TransportException when it cannot open a socket" do
-      ::Socket.should_receive(:new).and_raise(StandardError)
+      ::Socket.should_receive(:getaddrinfo).with("localhost", 9090, nil, ::Socket::SOCK_STREAM).and_return([[]])
       lambda { @socket.open }.should raise_error(Thrift::TransportException) { |e| e.type.should == Thrift::TransportException::NOT_OPEN }
     end