class Protocol::Redis::Connection

Constants

CRLF

Attributes

count[R]

@attr [Integer] Number of requests sent.

stream[R]

Public Class Methods

client(stream)
Alias for: new
new(stream) click to toggle source
# File lib/protocol/redis/connection.rb, line 30
def initialize(stream)
        @stream = stream
        
        # Number of requests sent:
        @count = 0
end
Also aliased as: client

Public Instance Methods

close() click to toggle source
# File lib/protocol/redis/connection.rb, line 42
def close
        @stream.close
end
closed?() click to toggle source
# File lib/protocol/redis/connection.rb, line 54
def closed?
        @stream.closed?
end
flush() click to toggle source
# File lib/protocol/redis/connection.rb, line 50
def flush
        @stream.flush
end
read_data(length) click to toggle source
# File lib/protocol/redis/connection.rb, line 84
def read_data(length)
        buffer = @stream.read(length) or @stream.eof!
        
        # Eat trailing whitespace because length does not include the CRLF:
        @stream.read(2) or @stream.eof!
        
        return buffer
end
read_object() click to toggle source
# File lib/protocol/redis/connection.rb, line 93
def read_object
        line = read_line or raise EOFError
        
        token = line.slice!(0, 1)
        
        case token
        when '$'
                length = line.to_i
                
                if length == -1
                        return nil
                else
                        return read_data(length)
                end
        when '*'
                count = line.to_i
                
                # Null array (https://redis.io/topics/protocol#resp-arrays):
                return nil if count == -1
                
                array = Array.new(count) {read_object}
                
                return array
        when ':'
                return line.to_i
        
        when '-'
                raise ServerError.new(line)
        
        when '+'
                return line
        
        else
                @stream.flush
                
                raise NotImplementedError, "Implementation for token #{token} missing"
        end
        
        # TODO: If an exception (e.g. Async::TimeoutError) propagates out of this function, perhaps @stream should be closed? Otherwise it might be in a weird state.
end
Also aliased as: read_response
read_response()
Alias for: read_object
write_object(object) click to toggle source
# File lib/protocol/redis/connection.rb, line 71
def write_object(object)
        case object
        when String
                write_lines("$#{object.bytesize}", object)
        when Array
                write_array(object)
        when Integer
                write_lines(":#{object}")
        else
                write_object(object.to_redis)
        end
end
write_request(arguments) click to toggle source

The redis server doesn't want actual objects (e.g. integers) but only bulk strings. So, we inline it for performance.

# File lib/protocol/redis/connection.rb, line 59
def write_request(arguments)
        write_lines("*#{arguments.size}")
        
        @count += 1
        
        arguments.each do |argument|
                string = argument.to_s
                
                write_lines("$#{string.bytesize}", string)
        end
end

Private Instance Methods

read_line() click to toggle source
# File lib/protocol/redis/connection.rb, line 153
def read_line
        @stream.gets(CRLF, chomp: true)
end
write_lines(*arguments) click to toggle source

In the case of Redis, we do not want to perform a flush in every line, because each Redis command contains several lines. Flushing once per command is more efficient because it avoids unnecessary writes to the socket.

# File lib/protocol/redis/connection.rb, line 142
def write_lines(*arguments)
        if arguments.empty?
                @stream.write(CRLF)
        else
                arguments.each do |arg|
                        @stream.write(arg)
                        @stream.write(CRLF)
                end
        end
end