Module: Sensu::Redis

Extended by:
Utilities
Defined in:
lib/sensu/redis.rb,
lib/sensu/redis/client.rb,
lib/sensu/redis/sentinel.rb,
lib/sensu/redis/utilities.rb,
lib/sensu/redis/client/errors.rb,
lib/sensu/redis/client/constants.rb

Defined Under Namespace

Modules: Utilities Classes: Client, CommandError, ConnectionError, ProtocolError, Sentinel

Constant Summary collapse

OK =

RESP (REdis Serialization Protocol) response type characters and delimiter (redis.io/topics/protocol).

"OK".freeze
MINUS =
"-".freeze
PLUS =
"+".freeze
COLON =
":".freeze
DOLLAR =
"$".freeze
ASTERISK =
"*".freeze
DELIM =
"\r\n".freeze
INCOMPLETE =

Redis response line parser incomplete data return value.

"incomp".freeze
TRUE_VALUES =

Redis response boolean values.

%w[1 OK].freeze
PUBSUB_RESPONSES =

Redis pubsub response type values.

%w[message unsubscribe].freeze
COMMANDS =

Redis commands that are supported by this library.

[
  "ping",
  "set",
  "setnx",
  "get",
  "getset",
  "del",
  "mget",
  "info",
  "sadd",
  "smembers",
  "sismember",
  "srem",
  "scard",
  "hset",
  "hsetnx",
  "hget",
  "hgetall",
  "hdel",
  "hincrby",
  "rpush",
  "lpush",
  "rpop",
  "blpop",
  "ltrim",
  "lrange",
  "llen",
  "exists",
  "hexists",
  "ttl",
  "expire",
  "flushdb",
  "incr",
  "multi",
  "exec",
  "publish"
].freeze
AUTH_COMMAND =

Redis commands.

"auth".freeze
SELECT_COMMAND =
"select".freeze
INFO_COMMAND =
"info".freeze
SUBSCRIBE_COMMAND =
"subscribe".freeze
UNSUBSCRIBE_COMMAND =
"unsubscribe".freeze
BOOLEAN_PROCESSOR =

Boolean Redis response value processor.

lambda{|r| TRUE_VALUES.include?(r.to_s)}
RESPONSE_PROCESSORS =

Redis response value processors.

{
  "auth" => BOOLEAN_PROCESSOR,
  "exists" => BOOLEAN_PROCESSOR,
  "hexists" => BOOLEAN_PROCESSOR,
  "sismember" => BOOLEAN_PROCESSOR,
  "sadd" => BOOLEAN_PROCESSOR,
  "srem" => BOOLEAN_PROCESSOR,
  "setnx" => BOOLEAN_PROCESSOR,
  "del" => BOOLEAN_PROCESSOR,
  "expire" => BOOLEAN_PROCESSOR,
  "select" => BOOLEAN_PROCESSOR,
  "hset" => BOOLEAN_PROCESSOR,
  "hdel" => BOOLEAN_PROCESSOR,
  "hsetnx" => BOOLEAN_PROCESSOR,
  "hgetall" => lambda{|r| Hash[*r]},
  "info" => lambda{|r|
    info = {}
    r.each_line do |line|
      line.chomp!
      unless line.empty?
        k, v = line.split(":", 2)
        info[k.to_sym] = v
      end
    end
    info
  }
}

Class Method Summary collapse

Methods included from Utilities

ip_address?, resolve_host, resolve_hostname

Class Method Details

.connect(options = {}) { ... } ⇒ Object

Connect to Redis using the provided connection options.

Parameters:

  • options (String, Hash) (defaults to: {})

Yields:

  • callback to be called with the redis connection object.


83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/sensu/redis.rb', line 83

def connect(options={}, &block)
  case options
  when String
    options = parse_url(options)
  when nil
    options = {}
  end
  options[:host] ||= "127.0.0.1"
  options[:port] ||= 6379
  case
  when options[:sentinels].is_a?(String)
    raw_urls = options[:sentinels]
    options[:sentinels] = raw_urls.split(',').map { |url| parse_url(url) }
  when options[:sentinels].is_a?(Array) && options[:sentinels].length > 0
    connect_via_sentinel(options, &block)
  else
    connect_direct(options, &block)
  end
end

.connect_direct(options) { ... } ⇒ Object

Connect to the current Redis master directly, using the provided connection options. This method uses `resolve_host()` to first resolve the provided host, if it's not already an IP address. Resolving the hostname upfront guards against lookup failures that would cause the Sensu process to crash. Upfront hostname resolution also allows this Redis library to work with Amazon AWS ElastiCache & where DNS is used as a failover mechanism.

Parameters:

  • options (Hash)

Yields:

  • callback to be called with the redis connection object.


65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/sensu/redis.rb', line 65

def connect_direct(options, &block)
  resolve_host(options[:host]) do |ip_address|
    if ip_address.nil?
      EM::Timer.new(1) do
        connect_direct(options, &block)
      end
    else
      redis = EM.connect(ip_address, options[:port], Client, options)
      redis.logger = @logger
      block.call(redis)
    end
  end
end

.connect_via_sentinel(options) { ... } ⇒ Object

Connect to the current Redis master via Sentinel. Sentinel will resolve the current Redis master host and port.

Parameters:

  • options (Hash)

Yields:

  • callback to be called with the redis connection object.


43
44
45
46
47
48
49
50
51
52
# File 'lib/sensu/redis.rb', line 43

def connect_via_sentinel(options, &block)
  sentinel = Sentinel.new(options)
  sentinel.logger = @logger
  sentinel.resolve do |host, port|
    redis = EM.connect(host, port, Client, options)
    redis.logger = @logger
    redis.sentinel = sentinel
    block.call(redis)
  end
end

.logger=(logger) ⇒ Object

Set the Redis logger.

Parameters:

  • logger (Object)

    Redis logger.


16
17
18
# File 'lib/sensu/redis.rb', line 16

def logger=(logger)
  @logger = logger
end

.parse_url(url) ⇒ Hash

Parse a Redis URL. An argument error exception is thrown if this method is unable to parse the provided URL string.

Parameters:

  • url (String)

Returns:

  • (Hash)

    Redis connection options.


25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/sensu/redis.rb', line 25

def parse_url(url)
  begin
    uri = URI.parse(url)
    {
      :host => uri.host,
      :port => uri.port,
      :password => uri.password
    }
  rescue
    raise ArgumentError, "invalid redis url"
  end
end