Class: Sensu::Redis::Sentinel

Inherits:
Object
  • Object
show all
Defined in:
lib/sensu/redis/sentinel.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Sentinel

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()`.

Parameters:

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

    containing the standard Redis connection settings.



16
17
18
19
# 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

Instance Attribute Details

#loggerObject

Returns the value of attribute logger.



7
8
9
# File 'lib/sensu/redis/sentinel.rb', line 7

def logger
  @logger
end

Instance Method Details

#connect_to_sentinel(options = {}) ⇒ Object

Connect to a Sentinel instance.

Parameters:

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

    containing the host and port.

Returns:

  • (Object)

    Sentinel connection.



25
26
27
28
29
# 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].to_i, Client, options)
end

#connect_to_sentinels(sentinels) ⇒ Array

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

Parameters:

  • sentinels (Array)

Returns:

  • (Array)

    of Sentinel connection objects.



36
37
38
39
40
# 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) { ... } ⇒ Object

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

Parameters:

  • sentinel (Object)

    connection.

  • seconds (Integer)

    before timeout.

Yields:

  • callback called when Sentinel resolves the current Redis master address (host & port).



67
68
69
70
71
72
73
# 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 { ... } ⇒ Object

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

Yields:

  • callback called when Sentinel resolves the current Redis master address (host & port).



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# 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 { ... } ⇒ Object

Retry ‘resolve()` with the provided callback.

Yields:

  • callback called when Sentinel resolves the current Redis master address (host & port).



54
55
56
57
58
# File 'lib/sensu/redis/sentinel.rb', line 54

def retry_resolve(&block)
  EM::Timer.new(1) do
    resolve(&block)
  end
end

#select_a_sentinelObject

Select a Sentinel connection object that is currently connected.

Returns:

  • (Object)

    Sentinel connection.



46
47
48
# File 'lib/sensu/redis/sentinel.rb', line 46

def select_a_sentinel
  @sentinels.select { |sentinel| sentinel.connected? }.shuffle.first
end