class IProto::TCPSocket
TODO: timeouts
Public Class Methods
new(host, port, reconnect = true)
click to toggle source
# File lib/iproto/tcp_socket.rb, line 6 def initialize(host, port, reconnect = true) @addr = [host, port] @reconnect_timeout = Numeric === reconnect ? reconnect : DEFAULT_RECONNECT @reconnect = !!reconnect @socket = nil @reconnect_time = Time.now - 1 @retry = true end
Public Instance Methods
_raise_disconnected(message, _raise = true)
click to toggle source
# File lib/iproto/tcp_socket.rb, line 84 def _raise_disconnected(message, _raise = true) old_socket = @socket if @reconnect @socket = nil @reconnect_time = Time.now + @reconnect_timeout else @socket = :disconnected end case _raise when true raise Disconnected, message when :retry begin # if request were sent, then we will not have EPIPE exception old_socket.send '\x00', 0 rescue Errno::EPIPE # OS knows that socket is closed, and request were not sent raise Retry else # OS didn't notice socket is closed, request were sent probably raise Disconnected, message end end end
close()
click to toggle source
# File lib/iproto/tcp_socket.rb, line 15 def close @reconnect = false if @socket @socket.close rescue nil @socket = :disconnected end end
connected?()
click to toggle source
# File lib/iproto/tcp_socket.rb, line 23 def connected? @socket && @socket != :disconnected end
could_be_connected?()
click to toggle source
# File lib/iproto/tcp_socket.rb, line 27 def could_be_connected? @socket ? @socket != :disconnected : (@reconnect || @reconnect_time < Time.now) end
recv_header(request_id)
click to toggle source
end ConnectionAPI
# File lib/iproto/tcp_socket.rb, line 70 def recv_header(request_id) header = socket.read(HEADER_SIZE) or _raise_disconnected('disconnected while read', @retry ? :retry : true) response_size = ::BinUtils.get_int32_le(header, 4) recv_request_id = ::BinUtils.get_int32_le(header, 8) unless request_id == recv_request_id raise UnexpectedResponse.new("Waiting response for request_id #{request_id}, but received for #{recv_request_id}") end response_size end
recv_response(response_size)
click to toggle source
# File lib/iproto/tcp_socket.rb, line 80 def recv_response(response_size) socket.read(response_size) or _raise_disconnected('disconnected while read', true) end
send_request(request_type, body)
click to toggle source
begin ConnectionAPI
# File lib/iproto/tcp_socket.rb, line 53 def send_request(request_type, body) unless could_be_connected? raise Disconnected, "connection is closed" end begin request_id = next_request_id socket.send pack_request(request_type, request_id, body), 0 response_size = recv_header request_id recv_response response_size rescue Errno::EPIPE, Retry => e _raise_disconnected(e, !@retry) @retry = false retry end end
socket()
click to toggle source
# File lib/iproto/tcp_socket.rb, line 32 def socket if (sock = @socket) sock != :disconnected ? sock : raise(Disconnected, "disconnected earlier") else sock = @socket = ::TCPSocket.new(*@addr) sock.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) @retry = true end sock rescue Errno::ECONNREFUSED => e unless @reconnect @socket = :disconnected else @reconnect_time = Time.now + @reconnect_timeout end raise CouldNotConnect, e end