sensu-redis 0.1.9 → 0.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d9953079714c141b83f7e59b50a9d75fa0474bab
4
- data.tar.gz: 96880d16d145c74b1769a8efb02805f7c04b5fee
3
+ metadata.gz: c8d58f678c26c38a696d2ce0235d79cd48d24c0b
4
+ data.tar.gz: 516f96d065dfb3a80ad469c2751b4693bdede13e
5
5
  SHA512:
6
- metadata.gz: b0c05605ee8d75b1a1922942ef34df14669bac9ddaf319bad36afd29f8002ecd8a1051151139f9a397aa0f245d42739b69578d5d2b6725054958a26f26231515
7
- data.tar.gz: f7b6d0486645d5170d41331a04fa198fbacd300c8690d93c1493a7945e7e3d415d363abd879c486416f3da8adf47a83ce4cbbb83e7cbd386b49dc0285fb4b701
6
+ metadata.gz: d128b9760fe34f3fb03c111d214b918ba243b9674b475b2801e0d631f5781650b81cc27518705974d08d53642a0f84aaa742cbebab6e2c1f19a379ff7384131c
7
+ data.tar.gz: c5ea8e91f0998b563f77dc353ba82383e8a5b294aa18c62bd878e599859224b2769f77ec369662a2e91b9e18500fd118a66123346348d63ee0c10beba259efe6
@@ -7,6 +7,11 @@ require "uri"
7
7
  module Sensu
8
8
  module Redis
9
9
  class << self
10
+ # Parse a Redis URL. An argument error exception is thrown if
11
+ # this method is unable to parse the provided URL string.
12
+ #
13
+ # @param url [String]
14
+ # @return [Hash] Redis connection options.
10
15
  def parse_url(url)
11
16
  begin
12
17
  uri = URI.parse(url)
@@ -20,24 +25,35 @@ module Sensu
20
25
  end
21
26
  end
22
27
 
28
+ # Connect to the current Redis master via Sentinel. Sentinel
29
+ # will resolve the current Redis master host and port.
30
+ #
31
+ # @param options [Hash]
32
+ # @yield callback to be called with the redis connection object.
23
33
  def connect_via_sentinel(options, &block)
24
34
  sentinel = Sentinel.new(options)
25
35
  sentinel.callback do
26
36
  sentinel.resolve do |host, port|
27
- block.call(EM.connect(host, port, Client, options))
28
- end
29
- end
30
- sentinel.errback do
31
- EM::Timer.new(3) do
32
- connect_via_sentinel(options, &block)
37
+ redis = EM.connect(host, port, Client, options)
38
+ redis.sentinel = sentinel
39
+ block.call(redis)
33
40
  end
34
41
  end
35
42
  end
36
43
 
44
+ # Connect to the current Redis master directly, using the
45
+ # provided connection options.
46
+ #
47
+ # @param options [Hash]
48
+ # @yield callback to be called with the redis connection object.
37
49
  def connect_direct(options, &block)
38
50
  block.call(EM.connect(options[:host], options[:port], Client, options))
39
51
  end
40
52
 
53
+ # Connect to Redis using the provided connection options.
54
+ #
55
+ # @param options [String,Hash]
56
+ # @yield callback to be called with the redis connection object.
41
57
  def connect(options={}, &block)
42
58
  case options
43
59
  when String
@@ -45,6 +61,8 @@ module Sensu
45
61
  when nil
46
62
  options = {}
47
63
  end
64
+ options[:host] ||= "127.0.0.1"
65
+ options[:port] ||= 6379
48
66
  if options[:sentinels].is_a?(Array)
49
67
  connect_via_sentinel(options, &block)
50
68
  else
@@ -7,6 +7,8 @@ module Sensu
7
7
  class Client < EM::Connection
8
8
  include EM::Deferrable
9
9
 
10
+ attr_accessor :sentinel
11
+
10
12
  # Initialize the connection, creating the Redis command methods,
11
13
  # and setting the default connection options and callbacks.
12
14
  def initialize(options={})
@@ -17,15 +19,28 @@ module Sensu
17
19
  @password = options[:password]
18
20
  @auto_reconnect = options.fetch(:auto_reconnect, true)
19
21
  @reconnect_on_error = options.fetch(:reconnect_on_error, true)
20
- @error_callback = lambda do |error|
21
- raise(error)
22
- end
22
+ @error_callback = Proc.new {}
23
23
  @reconnect_callbacks = {
24
- :before => lambda {},
25
- :after => lambda {}
24
+ :before => Proc.new {},
25
+ :after => Proc.new {}
26
26
  }
27
27
  end
28
28
 
29
+ # Determine the current Redis master address. If Sentinel was
30
+ # used to determine the original address, use it again. If
31
+ # Sentinel is not being used, return the host and port used when
32
+ # the connection was first established.
33
+ #
34
+ # @yield callback called when the current Redis master host and
35
+ # port has been determined.
36
+ def determine_address(&block)
37
+ if @sentinel
38
+ @sentinel.resolve(&block)
39
+ else
40
+ block.call(@host, @port)
41
+ end
42
+ end
43
+
29
44
  # Set the connection error callback. This callback is called
30
45
  # when the connection encounters either a connection, protocol,
31
46
  # or command error.
@@ -68,7 +83,9 @@ module Sensu
68
83
  @reconnect_callbacks[:before].call unless @reconnecting
69
84
  @reconnecting = true
70
85
  EM.add_timer(1) do
71
- reconnect(@host, @port)
86
+ determine_address do |host, port|
87
+ reconnect(host, port)
88
+ end
72
89
  end
73
90
  end
74
91
 
@@ -107,7 +124,7 @@ module Sensu
107
124
  # Send a Redis command using RESP multi bulk. This method sends
108
125
  # data to Redis using EM connection `send_data()`.
109
126
  #
110
- # @params [Array<Object>] *arguments
127
+ # @param [Array<Object>] *arguments
111
128
  def send_command_data(*arguments)
112
129
  data = "*#{arguments.size}#{DELIM}"
113
130
  arguments.each do |value|
@@ -121,8 +138,8 @@ module Sensu
121
138
  # callback. This method calls `send_command_data()` for RESP
122
139
  # multi bulk and transmission.
123
140
  #
124
- # @params command [String]
125
- # @params [Array<Object>] *arguments
141
+ # @param command [String]
142
+ # @param [Array<Object>] *arguments
126
143
  # @yield command reponse callback
127
144
  def send_command(command, *arguments, &block)
128
145
  send_command_data(command, *arguments)
@@ -132,8 +149,8 @@ module Sensu
132
149
  # Send a Redis command once the Redis connection has been
133
150
  # established (EM Deferable succeeded).
134
151
  #
135
- # @params command [String]
136
- # @params [Array<Object>] *arguments
152
+ # @param command [String]
153
+ # @param [Array<Object>] *arguments
137
154
  # @yield command reponse callback
138
155
  def redis_command(command, *arguments, &block)
139
156
  if @deferred_status == :succeeded
@@ -6,19 +6,38 @@ module Sensu
6
6
  class Sentinel
7
7
  include EM::Deferrable
8
8
 
9
+ # Initialize the Sentinel connections. The default Redis master
10
+ # name is "mymaster", which is the same name that the Sensu HA
11
+ # Redis documentation uses. The master name must be set
12
+ # correctly in order for `resolve()`.
13
+ #
14
+ # @param options [Hash] containing the standard Redis
15
+ # connection settings.
9
16
  def initialize(options={})
10
- @options = options
11
- @master_name = options[:host] || "mymaster"
12
- @sentinels = connect_to_sentinels(@options[:sentinels])
17
+ @master = options[:master] || "mymaster"
18
+ @sentinels = connect_to_sentinels(options[:sentinels])
13
19
  end
14
20
 
21
+ # Connect to a Sentinel instance. A successful connection will
22
+ # set the deferrable status to `:successful`, triggering any
23
+ # queued Sentinel callback calls (e.g. `resolve()`).
24
+ #
25
+ # @param host [String]
26
+ # @param port [Integer]
27
+ # @return [Object] Sentinel connection.
15
28
  def connect_to_sentinel(host, port)
16
29
  connection = EM.connect(host, port, Client)
17
30
  connection.callback do
18
31
  succeed
19
32
  end
33
+ connection
20
34
  end
21
35
 
36
+ # Connect to all Sentinel instances. This method defaults the
37
+ # Sentinel host and port if either have not been set.
38
+ #
39
+ # @param sentinels [Array]
40
+ # @return [Array] of Sentinel connection objects.
22
41
  def connect_to_sentinels(sentinels)
23
42
  sentinels.map do |sentinel|
24
43
  host = sentinel[:host] || "127.0.0.1"
@@ -27,18 +46,41 @@ module Sensu
27
46
  end
28
47
  end
29
48
 
49
+ # Select a Sentinel connection object that is currently
50
+ # connected.
51
+ #
52
+ # @return [Object] Sentinel connection.
30
53
  def select_a_sentinel
31
54
  @sentinels.select { |sentinel| sentinel.connected? }.shuffle.first
32
55
  end
33
56
 
34
- def resolve
57
+ # Retry `resolve()` with the provided callback.
58
+ #
59
+ # @yield callback called when Sentinel resolves the current
60
+ # Redis master address (host & port).
61
+ def retry_resolve(&block)
62
+ EM::Timer.new(1) do
63
+ resolve(&block)
64
+ end
65
+ end
66
+
67
+ # Resolve the current Redis master via Sentinel. The correct
68
+ # Redis master name is required for this method to work.
69
+ #
70
+ # @yield callback called when Sentinel resolves the current
71
+ # Redis master address (host & port).
72
+ def resolve(&block)
35
73
  sentinel = select_a_sentinel
36
74
  if sentinel.nil?
37
- fail
75
+ retry_resolve(&block)
38
76
  else
39
77
  sentinel.callback do
40
- sentinel.send_command("sentinel", "get-master-addr-by-name", @master_name) do |host, port|
41
- yield(host, port)
78
+ sentinel.send_command("sentinel", "get-master-addr-by-name", @master) do |host, port|
79
+ if host && port
80
+ block.call(host, port)
81
+ else
82
+ retry_resolve(&block)
83
+ end
42
84
  end
43
85
  end
44
86
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = "sensu-redis"
5
- spec.version = "0.1.9"
5
+ spec.version = "0.1.10"
6
6
  spec.authors = ["Sean Porter"]
7
7
  spec.email = ["portertech@gmail.com"]
8
8
  spec.summary = "The Sensu Redis client library"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sensu-redis
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.9
4
+ version: 0.1.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Porter