class RedisClient::RubyConnection
def connect
def connect socket = if @config.path UNIXSocket.new(@config.path) else sock = if SUPPORTS_RESOLV_TIMEOUT begin Socket.tcp(@config.host, @config.port, connect_timeout: @connect_timeout, resolv_timeout: @connect_timeout) rescue Errno::ETIMEDOUT => timeout_error timeout_error.message << ": #{@connect_timeout}s" raise end else Socket.tcp(@config.host, @config.port, connect_timeout: @connect_timeout) end # disables Nagle's Algorithm, prevents multiple round trips with MULTI sock.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) enable_socket_keep_alive(sock) sock end if @config.ssl socket = OpenSSL::SSL::SSLSocket.new(socket, @config.ssl_context) socket.hostname = @config.host loop do case status = socket.connect_nonblock(exception: false) when :wait_readable socket.to_io.wait_readable(@connect_timeout) or raise CannotConnectError.with_config("", config) when :wait_writable socket.to_io.wait_writable(@connect_timeout) or raise CannotConnectError.with_config("", config) when socket break else raise "Unexpected `connect_nonblock` return: #{status.inspect}" end end end @io = BufferedIO.new( socket, read_timeout: @read_timeout, write_timeout: @write_timeout, ) true rescue SystemCallError, OpenSSL::SSL::SSLError, SocketError => error socket&.close raise CannotConnectError, error.message, error.backtrace end