sensu-redis 0.1.9 → 0.1.10

Sign up to get free protection for your applications and to get access to all the features.
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