Module: Sensu::Redis::Parser

Included in:
Client
Defined in:
lib/sensu/redis/parser.rb

Overview

Sensu Module for parsing RESP (REdis Serialization Protocol). You can read about RESP @ redis.io/topics/protocol This module calls methods provided by other Sensu Redis modules:

Sensu::Redis::Processor.dispatch_error()
Sensu::Redis::Processor.dispatch_response()
Sensu::Redis::Processor.begin_multibulk()
Sensu::Redis::Connection.error()

Instance Method Summary collapse

Instance Method Details

#parse_line(line) ⇒ Object

Parse a RESP line.

Parameters:

  • line (String)


17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/sensu/redis/parser.rb', line 17

def parse_line(line)
  # Trim off the response type and delimiter (\r\n).
  response = line.slice(1..-3)
  # First character indicates response type.
  case line[0, 1]
  when MINUS # Error, e.g. -ERR
    dispatch_error(response)
  when PLUS # String, e.g. +OK
    dispatch_response(response)
  when DOLLAR # Bulk string, e.g. $3\r\nfoo\r\n
    response_size = Integer(response)
    if response_size == -1 # No data, return nil.
      dispatch_response(nil)
    elsif @buffer.size >= response_size + 2 # Complete data.
      dispatch_response(@buffer.slice!(0, response_size))
      @buffer.slice!(0,2) # Discard delimeter (\r\n).
    else # Incomplete, have data pushed back into buffer.
      return INCOMPLETE
    end
  when COLON # Integer, e.g. :8
    dispatch_response(Integer(response))
  when ASTERISK # Array, e.g. *2\r\n$3\r\foo\r\n$3\r\nbar\r\n
    multibulk_count = Integer(response)
    if multibulk_count == -1 || multibulk_count == 0 # No data, return [].
      dispatch_response(EMPTY_ARRAY)
    else
      begin_multibulk(multibulk_count) # Accumulate responses.
    end
  else
    error(ProtocolError, "response type not recognized: #{line.strip}")
  end
end

#receive_data(data) ⇒ Object

EM connection receive data, parse incoming data using RESP (‘parse_line()`).

Parameters:

  • data (String)


54
55
56
57
58
59
60
61
62
63
# File 'lib/sensu/redis/parser.rb', line 54

def receive_data(data)
  (@buffer ||= '') << data
  while index = @buffer.index(DELIM)
    line = @buffer.slice!(0, index+2)
    if parse_line(line) == INCOMPLETE
      @buffer[0...0] = line
      break
    end
  end
end