Module: CgminerApiClient::SocketWithTimeout

Included in:
Miner
Defined in:
lib/cgminer_api_client/socket_with_timeout.rb

Instance Method Summary collapse

Instance Method Details

#open_socket(host, port, timeout) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/cgminer_api_client/socket_with_timeout.rb', line 5

def open_socket(host, port, timeout)
  addr     = Socket.getaddrinfo(host, nil)
  sockaddr = Socket.pack_sockaddr_in(port, addr[0][3])

  Socket.new(Socket.const_get(addr[0][0]), Socket::SOCK_STREAM, 0).tap do |socket|
    socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)

    begin
      socket.connect_nonblock(sockaddr)
    rescue IO::WaitWritable
      if socket.wait_writable(timeout)
        begin
          socket.connect_nonblock(sockaddr)
        rescue Errno::EISCONN
          # On Linux, the second connect_nonblock on a now-writable
          # socket reports EISCONN to mean "the connection completed
          # while we were waiting." Treat as success. On other
          # platforms the second call returns 0 cleanly and this
          # branch never fires.
        rescue StandardError
          socket.close
          raise
        end
      else
        socket.close
        raise CgminerApiClient::TimeoutError, "Connection to #{host}:#{port} timed out after #{timeout}s"
      end
    end
  end
end