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 +4 -4
- data/lib/sensu/redis.rb +24 -6
- data/lib/sensu/redis/client.rb +28 -11
- data/lib/sensu/redis/sentinel.rb +49 -7
- data/sensu-redis.gemspec +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c8d58f678c26c38a696d2ce0235d79cd48d24c0b
|
4
|
+
data.tar.gz: 516f96d065dfb3a80ad469c2751b4693bdede13e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d128b9760fe34f3fb03c111d214b918ba243b9674b475b2801e0d631f5781650b81cc27518705974d08d53642a0f84aaa742cbebab6e2c1f19a379ff7384131c
|
7
|
+
data.tar.gz: c5ea8e91f0998b563f77dc353ba82383e8a5b294aa18c62bd878e599859224b2769f77ec369662a2e91b9e18500fd118a66123346348d63ee0c10beba259efe6
|
data/lib/sensu/redis.rb
CHANGED
@@ -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
|
-
|
28
|
-
|
29
|
-
|
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
|
data/lib/sensu/redis/client.rb
CHANGED
@@ -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 =
|
21
|
-
raise(error)
|
22
|
-
end
|
22
|
+
@error_callback = Proc.new {}
|
23
23
|
@reconnect_callbacks = {
|
24
|
-
:before =>
|
25
|
-
:after =>
|
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
|
-
|
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
|
-
# @
|
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
|
-
# @
|
125
|
-
# @
|
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
|
-
# @
|
136
|
-
# @
|
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
|
data/lib/sensu/redis/sentinel.rb
CHANGED
@@ -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
|
-
@
|
11
|
-
@
|
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
|
-
|
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
|
-
|
75
|
+
retry_resolve(&block)
|
38
76
|
else
|
39
77
|
sentinel.callback do
|
40
|
-
sentinel.send_command("sentinel", "get-master-addr-by-name", @
|
41
|
-
|
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
|
data/sensu-redis.gemspec
CHANGED