class Protocol::Redis::Connection
Constants
- CRLF
Attributes
count[R]
@attr [Integer] Number of requests sent.
stream[R]
Public Class Methods
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
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