Class: Protocol::Redis::Connection
- Inherits:
-
Object
- Object
- Protocol::Redis::Connection
- Defined in:
- lib/protocol/redis/connection.rb
Overview
Represents a Redis protocol connection handling low-level communication.
Constant Summary collapse
- CRLF =
"\r\n".freeze
Instance Attribute Summary collapse
- #count ⇒ Object readonly
-
#stream ⇒ Object
readonly
Returns the value of attribute stream.
Instance Method Summary collapse
-
#close ⇒ Object
Close the underlying stream connection.
-
#closed? ⇒ Boolean
Check if the connection is closed.
-
#flush ⇒ Object
Flush any buffered data to the stream.
-
#initialize(stream) ⇒ Connection
constructor
Initialize a new connection with the provided stream.
-
#read_data(length) ⇒ Object
Read data of specified length from the stream.
-
#read_object ⇒ Object
(also: #read_response)
Read and parse a Redis object from the stream.
-
#write_array(array) ⇒ Object
Write a Redis array to the stream.
-
#write_object(object) ⇒ Object
Write a Redis object to the stream.
-
#write_request(arguments) ⇒ Object
The redis server doesn’t want actual objects (e.g. integers) but only bulk strings.
Constructor Details
#initialize(stream) ⇒ Connection
Initialize a new connection with the provided stream.
16 17 18 19 20 21 |
# File 'lib/protocol/redis/connection.rb', line 16 def initialize(stream) @stream = stream # Number of requests sent: @count = 0 end |
Instance Attribute Details
#count ⇒ Object (readonly)
26 27 28 |
# File 'lib/protocol/redis/connection.rb', line 26 def count @count end |
#stream ⇒ Object (readonly)
Returns the value of attribute stream.
23 24 25 |
# File 'lib/protocol/redis/connection.rb', line 23 def stream @stream end |
Instance Method Details
#close ⇒ Object
Close the underlying stream connection.
29 30 31 |
# File 'lib/protocol/redis/connection.rb', line 29 def close @stream.close end |
#closed? ⇒ Boolean
Check if the connection is closed.
45 46 47 |
# File 'lib/protocol/redis/connection.rb', line 45 def closed? @stream.closed? end |
#flush ⇒ Object
Flush any buffered data to the stream.
39 40 41 |
# File 'lib/protocol/redis/connection.rb', line 39 def flush @stream.flush end |
#read_data(length) ⇒ Object
Read data of specified length from the stream.
92 93 94 95 96 97 98 99 |
# File 'lib/protocol/redis/connection.rb', line 92 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 ⇒ Object Also known as: read_response
Read and parse a Redis object from the stream.
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/protocol/redis/connection.rb', line 105 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 UnknownTokenError, token.inspect 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 |
#write_array(array) ⇒ Object
Write a Redis array to the stream.
81 82 83 84 85 86 87 |
# File 'lib/protocol/redis/connection.rb', line 81 def write_array(array) write_lines("*#{array.size}") array.each do |element| write_object(element) end end |
#write_object(object) ⇒ Object
Write a Redis object to the stream.
64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/protocol/redis/connection.rb', line 64 def write_object(object) case object when String write_lines("$#{object.bytesize}", object) when Array write_array(object) when Integer write_lines(":#{object}") when nil write_lines("$-1") else write_object(object.to_redis) end end |
#write_request(arguments) ⇒ Object
The redis server doesn’t want actual objects (e.g. integers) but only bulk strings. So, we inline it for performance.
50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/protocol/redis/connection.rb', line 50 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 |