class Tarantool16::Connection::Dumb
Constants
- EXCEPTION_FALSE
Public Class Methods
new(host, opts = {})
click to toggle source
# File lib/tarantool16/connection/dumb.rb, line 14 def initialize(host, opts = {}) _init_common(host, opts) @reconnect_time = now_f - 1 @socket = nil _connect end
Public Instance Methods
close()
click to toggle source
# File lib/tarantool16/connection/dumb.rb, line 48 def close @reconnect = false if @socket @socket.close rescue nil @socket = false @s = 0 end end
connected?()
click to toggle source
# File lib/tarantool16/connection/dumb.rb, line 57 def connected? @socket end
could_be_connected?()
click to toggle source
# File lib/tarantool16/connection/dumb.rb, line 61 def could_be_connected? @socket || (@socket.nil? && (@reconnect || @reconnect_time < now_f)) end
disconnect()
click to toggle source
# File lib/tarantool16/connection/dumb.rb, line 40 def disconnect if @socket @socket.close rescue nil @socket = nil @s = 0 end end
send_request(code, body, cb)
click to toggle source
# File lib/tarantool16/connection/dumb.rb, line 21 def send_request(code, body, cb) _connect syswrite format_request(code, next_sync, body) written = true response = _read_response rescue ::Errno::EPIPE, Retry => e @socket.close rescue nil @socket = nil if !written && @retry && @reconnect @retry = false retry end cb.call Option.error(nil, Disconnected, e.message) rescue StandardError => e cb.call Option.error(nil, e, nil) else cb.call response end
Private Instance Methods
_connect()
click to toggle source
# File lib/tarantool16/connection/dumb.rb, line 66 def _connect return if @socket unless could_be_connected? raise Disconnected, "connection is closed" end if _unix? @socket = Socket.unix(_unix_sock_path) elsif _tcp? @socket = Socket.new((_ipv6? ? Socket::AF_INET6 : Socket::AF_INET), Socket::SOCK_STREAM) @socket.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, 1) @socket.sync = true sockaddr = Socket.pack_sockaddr_in(*host_port.reverse) @retry = @reconnect if @timeout _connect_nonblock(sockaddr) else @socket.connect(sockaddr) end else raise "unsupported host option: #{@host.inspect}" end greeting = _read(IPROTO_GREETING_SIZE) unless greeting && greeting.bytesize == IPROTO_GREETING_SIZE raise Disconnected, "mailformed greeting #{greeting.inspect}" end @nbuf = "\x00\x00\x00\x00\x00".force_encoding('BINARY') parse_greeting greeting authenticate if @user rescue ::Errno::ECONNREFUSED, ::Errno::EPIPE, Disconnected, Timeout => e @socket.close rescue nil @socket = nil if !@reconnect @socket = false @s = 0 else @reconnect_time = now_f + @reconnect_timeout end raise CouldNotConnect, e.message end
_connect_nonblock(sockaddr)
click to toggle source
# File lib/tarantool16/connection/dumb.rb, line 107 def _connect_nonblock(sockaddr) expire = now_f + @timeout begin @socket.connect_nonblock(sockaddr) rescue IO::WaitWritable t = [@socket] IO.select(t, t, nil, expire - now_f) begin @socket.connect_nonblock(sockaddr) rescue Errno::EISCONN end end end
_read(n, buf=nil)
click to toggle source
# File lib/tarantool16/connection/dumb.rb, line 177 def _read(n, buf=nil) unless @timeout buf ? @socket.read(n, buf) : @socket.read(n) else expire = now_f + @timeout rbuf = nil while n > 0 case tbuf = _read_nonblock(n, buf) when String if rbuf rbuf << tbuf else rbuf = tbuf end buf = nil n -= tbuf.size when :wait_readable nf = now_f if expire <= nf raise Timeout, "response timeouted" else _wait_readable(expire - nf) end when nil raise EOFError end end return rbuf end end
_read_nonblock(n, buf)
click to toggle source
# File lib/tarantool16/connection/dumb.rb, line 210 def _read_nonblock(n, buf) if buf @socket.read_nonblock(n, buf, EXCEPTION_FALSE) else @socket.read_nonblock(n, EXCEPTION_FALSE) end end
_read_response()
click to toggle source
# File lib/tarantool16/connection/dumb.rb, line 152 def _read_response str = _read(5, @nbuf) unless str && str.bytesize == 5 # check if we sent request or not begin @socket.send("\x00", 0) rescue ::Errno::EPIPE # if OS knows that socket is closed, then request were not sent raise Retry else # otherwise request were sent raise Disconnected, "disconnected while read length" end end n = parse_size(str) raise n unless ::Integer === n resp = _read(n) raise Disconnected, "disconnected while read response" unless resp && resp.bytesize == n r = parse_response(resp) if r.ok? && r.sync != @s raise UnexpectedResponse, "sync mismatch: #{@s} != #{r.sync}" end r end
_wait_readable(timeout)
click to toggle source
# File lib/tarantool16/connection/dumb.rb, line 238 def _wait_readable(timeout) IO.select([@socket], nil, nil, timeout) end
_wait_writable(timeout)
click to toggle source
# File lib/tarantool16/connection/dumb.rb, line 247 def _wait_writable(timeout) @socket.wait_writable(timeout) end
authenticate()
click to toggle source
# File lib/tarantool16/connection/dumb.rb, line 147 def authenticate syswrite format_authenticate(@user, @passwd, @salt) _read_response.raise_if_error! end
syswrite(req)
click to toggle source
# File lib/tarantool16/connection/dumb.rb, line 121 def syswrite(req) unless @timeout if @socket.syswrite(req) != req.bytesize raise Retry, "Could not write message" end else expire = now_f begin until req.empty? n = @socket.write_nonblock(req) req = req[n..-1] end rescue IO::WaitWritable nf = now_f if expire <= nf raise Timeout, "response timeouted" else _wait_writable(expire - nf) retry end rescue Errno::EINTR retry end end end