Class: Protocol::Redis::Connection
- Inherits:
-
Object
- Object
- Protocol::Redis::Connection
- Defined in:
- lib/protocol/redis/connection.rb
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
- #closed? ⇒ Boolean
- #flush ⇒ Object
-
#initialize(stream) ⇒ Connection
constructor
A new instance of Connection.
- #read_data(length) ⇒ Object
- #read_object ⇒ Object (also: #read_response)
- #write_object(object) ⇒ Object
-
#write_request(arguments) ⇒ Object
The redis server doesn’t want actual objects (e.g. integers) but only bulk strings.
Constructor Details
#initialize(stream) ⇒ Connection
Returns a new instance of Connection.
30 31 32 33 34 35 |
# File 'lib/protocol/redis/connection.rb', line 30 def initialize(stream) @stream = stream # Number of requests sent: @count = 0 end |
Instance Attribute Details
#count ⇒ Object (readonly)
40 41 42 |
# File 'lib/protocol/redis/connection.rb', line 40 def count @count end |
#stream ⇒ Object (readonly)
Returns the value of attribute stream.
37 38 39 |
# File 'lib/protocol/redis/connection.rb', line 37 def stream @stream end |
Instance Method Details
#close ⇒ Object
42 43 44 |
# File 'lib/protocol/redis/connection.rb', line 42 def close @stream.close end |
#closed? ⇒ Boolean
54 55 56 |
# File 'lib/protocol/redis/connection.rb', line 54 def closed? @stream.closed? end |
#flush ⇒ Object
50 51 52 |
# File 'lib/protocol/redis/connection.rb', line 50 def flush @stream.flush end |
#read_data(length) ⇒ Object
84 85 86 87 88 89 90 91 |
# 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 ⇒ Object Also known as: read_response
93 94 95 96 97 98 99 100 101 102 103 104 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 |
# 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 |
#write_object(object) ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 82 |
# 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) ⇒ Object
The redis server doesn’t want actual objects (e.g. integers) but only bulk strings. So, we inline it for performance.
59 60 61 62 63 64 65 66 67 68 69 |
# 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 |