Module: Oxblood::Protocol

Defined in:
lib/oxblood/protocol.rb

Constant Summary collapse

SerializerError =
Class.new(RuntimeError)
ParserError =
Class.new(RuntimeError)
RError =
Class.new(RuntimeError)

Class Method Summary collapse

Class Method Details

.build_command(command = nil, *args) ⇒ String

Note:

Redis don't support nested arrays

Note:

Written in non-idiomatic ruby without error handling due to performance reasons

Serialize command to string according to Redis Protocol

Raises:

See Also:


102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/oxblood/protocol.rb', line 102

def build_command(command = nil, *args)
  return EMPTY_ARRAY_RESPONSE if command.nil?

  result = append!(command, COMMAND_HEADER.dup)
  size = 1
  args.each do |c|
    if Array === c
      c.each do |e|
        append!(e, result)
        size += 1
      end
    else
      append!(c, result)
      size += 1
    end
  end

  result.insert(1, size.to_s)
end

.parse(io) ⇒ String, ...

Parse redis response

Raises:

See Also:


52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/oxblood/protocol.rb', line 52

def parse(io)
  line = io.gets(TERMINATOR)

  case line[0]
  when SIMPLE_STRING
    line[1..-3]
  when ERROR
    RError.new(line[1..-3])
  when INTEGER
    line[1..-3].to_i
  when BULK_STRING
    return if line == NULL_BULK_STRING_RESPONSE

    body_length = line[1..-1].to_i

    case body_length
    when -1 then nil
    when 0 then
      # discard CRLF
      io.read(2)
      EMPTY_STRING
    else
      # string length plus CRLF
      body = io.read(body_length + 2)
      body[0..-3]
    end
  when ARRAY
    return if line == NULL_ARRAY_RESPONSE
    return EMPTY_ARRAY if line == EMPTY_ARRAY_RESPONSE

    size = line[1..-1].to_i

    Array.new(size) { parse(io) }
  else
    raise ParserError.new('Unsupported response type')
  end
end