class Sensu::Redis::Sentinel

Attributes

logger[RW]

Public Class Methods

new(options={}) click to toggle source

Initialize the Sentinel connections. The default Redis master name is “mymaster”, which is the same name that the Sensu HA Redis documentation uses. The master name must be set correctly in order for `resolve()`.

@param options [Hash] containing the standard Redis

connection settings.
# File lib/sensu/redis/sentinel.rb, line 16
def initialize(options={})
  @master = options[:master_group] || options[:master] || "mymaster"
  @sentinels = connect_to_sentinels(options[:sentinels])
end

Public Instance Methods

connect_to_sentinel(options={}) click to toggle source

Connect to a Sentinel instance.

@param options [Hash] containing the host and port. @return [Object] Sentinel connection.

# File lib/sensu/redis/sentinel.rb, line 25
def connect_to_sentinel(options={})
  options[:host] ||= "127.0.0.1"
  options[:port] ||= 26379
  EM.connect(options[:host], options[:port], Client, options)
end
connect_to_sentinels(sentinels) click to toggle source

Connect to all Sentinel instances. This method defaults the Sentinel host and port if either have not been set.

@param sentinels [Array] @return [Array] of Sentinel connection objects.

# File lib/sensu/redis/sentinel.rb, line 36
def connect_to_sentinels(sentinels)
  sentinels.map do |options|
    connect_to_sentinel(options)
  end
end
create_resolve_timeout(sentinel, seconds, &block) click to toggle source

Create a Sentinel master resolve timeout, causing the previous attempt to fail/cancel, while beginning another attempt.

@param sentinel [Object] connection. @param seconds [Integer] before timeout. @yield callback called when Sentinel resolves the current

Redis master address (host & port).
# File lib/sensu/redis/sentinel.rb, line 67
def create_resolve_timeout(sentinel, seconds, &block)
  EM::Timer.new(seconds) do
    sentinel.fail
    sentinel.succeed
    retry_resolve(&block)
  end
end
resolve(&block) click to toggle source

Resolve the current Redis master via Sentinel. The correct Redis master name is required for this method to work.

@yield callback called when Sentinel resolves the current

Redis master address (host & port).
# File lib/sensu/redis/sentinel.rb, line 80
def resolve(&block)
  sentinel = select_a_sentinel
  if sentinel.nil?
    if @logger
      @logger.debug("unable to determine redis master", {
        :reason => "not connected to a redis sentinel"
      })
      @logger.debug("retrying redis master resolution via redis sentinel")
    end
    retry_resolve(&block)
  else
    timeout = create_resolve_timeout(sentinel, 10, &block)
    sentinel.redis_command("sentinel", "get-master-addr-by-name", @master) do |host, port|
      timeout.cancel
      if host && port
        @logger.debug("redis master resolved via redis sentinel", {
          :host => host,
          :port => port.to_i
        }) if @logger
        block.call(host, port.to_i)
      else
        if @logger
          @logger.debug("unable to determine redis master", {
            :reason => "redis sentinel did not return a redis master host and port"
          })
          @logger.debug("retrying redis master resolution via redis sentinel")
        end
        retry_resolve(&block)
      end
    end
  end
end
retry_resolve(&block) click to toggle source

Retry `resolve()` with the provided callback.

@yield callback called when Sentinel resolves the current

Redis master address (host & port).
# File lib/sensu/redis/sentinel.rb, line 54
def retry_resolve(&block)
  EM::Timer.new(1) do
    resolve(&block)
  end
end
select_a_sentinel() click to toggle source

Select a Sentinel connection object that is currently connected.

@return [Object] Sentinel connection.

# File lib/sensu/redis/sentinel.rb, line 46
def select_a_sentinel
  @sentinels.select { |sentinel| sentinel.connected? }.shuffle.first
end