sensu-redis 0.1.4 → 0.1.5

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: 5b8895a42f4cb3e6563be8a39035bb93dc68d049
4
- data.tar.gz: 44cb3dbc56d3d2c16a0f6b53b3f7c607a7e4ba2e
3
+ metadata.gz: d506a4f9c1cb2989055fc0d1f60ad3f8828b5800
4
+ data.tar.gz: 21f5ddeb2c308b0bd972e5d55b18f76e0aa805e3
5
5
  SHA512:
6
- metadata.gz: 1e063207d57983942369babd6e2e2eafc350d722a70e270b3d7b132a8cb7ac3d7f6102874fcbac59bd6d0da866f8636eb7c16379e37ccd6acfc1f87422aec0dd
7
- data.tar.gz: a84187b8ac1dabb1709c07c64d3622d4d1060620b9631d67281c9d0a95121eca76830618f1dcdd20eec2f6573ddc7704a2b61962de6812b6a1a823ff0fd97420
6
+ metadata.gz: a315cfdb676056faf7767524e3e74fcbb881120fa8438d41b24a149ac9062599e8f8628771d62569e33f046726bbd76384345fce5ae22891619093ae4a10890e
7
+ data.tar.gz: ae11c67716d9a903df610b69183aed227fa113310ef5d5f084f23eeab049dc704d59f28c3fc51789496aa26d289ed9fea0094ecdd7cd332fa49bf986649e9fbe
@@ -16,53 +16,67 @@ module Sensu
16
16
  string.respond_to?(:bytesize) ? string.bytesize : string.size
17
17
  end
18
18
 
19
- # Send a Redis command using RESP multi bulk. This method is
20
- # called by the Redis command methods, which are created by
21
- # `create_command_methods()`, it simply implements RESP and
22
- # sends commands to Redis via EM connection `send_data()`.
23
- def send_command(*arguments)
24
- command = "*#{arguments.size}#{DELIM}"
19
+ # Send a Redis command using RESP multi bulk. This method sends
20
+ # data to Redis using EM connection `send_data()`.
21
+ #
22
+ # @params [Array<Object>] *arguments
23
+ def send_command_data(*arguments)
24
+ data = "*#{arguments.size}#{DELIM}"
25
25
  arguments.each do |value|
26
26
  value = value.to_s
27
- command << "$#{get_size(value)}#{DELIM}#{value}#{DELIM}"
27
+ data << "$#{get_size(value)}#{DELIM}#{value}#{DELIM}"
28
28
  end
29
- callback { send_data(command) }
29
+ send_data(data)
30
30
  end
31
31
 
32
- # Create Redis command methods. Command methods just wrap
33
- # `send_command()` and enqueue a response callback. This method
34
- # MUST be called in the connection object's `initialize()`.
35
- def create_command_methods!
32
+ # Send a Redis command and queue the associated response
33
+ # callback. This method calls `send_command_data()` for RESP
34
+ # multi bulk and transmission.
35
+ #
36
+ # @params command [String]
37
+ # @params [Array<Object>] *arguments
38
+ # @yield command reponse callback
39
+ def send_command(command, *arguments, &block)
36
40
  @response_callbacks ||= []
37
- REDIS_COMMANDS.each do |command|
38
- self.class.send(:define_method, command.to_sym) do |*arguments, &block|
39
- send_command(command, *arguments)
40
- @response_callbacks << [RESPONSE_PROCESSORS[command], block]
41
+ send_command_data(command, *arguments)
42
+ @response_callbacks << [RESPONSE_PROCESSORS[command], block]
43
+ end
44
+
45
+ # Send a Redis command once the Redis connection has been
46
+ # established (EM Deferable succeeded).
47
+ #
48
+ # @params command [String]
49
+ # @params [Array<Object>] *arguments
50
+ # @yield command reponse callback
51
+ def redis_command(command, *arguments, &block)
52
+ if @deferred_status == :succeeded
53
+ send_command(command, *arguments, &block)
54
+ else
55
+ callback do
56
+ send_command(command, *arguments, &block)
41
57
  end
42
58
  end
43
59
  end
44
60
 
45
- # Authenticate to Redis and select the correct DB, when
46
- # applicable. The auth and select Redis commands must be the
47
- # first commands (& callbacks) to run.
48
- #
49
- # @param password [String]
50
- # @param db [Integer]
51
- def auth_and_select_db(password=nil, db=nil)
52
- callbacks = @callbacks || []
53
- @callbacks = []
54
- send_command(AUTH_COMMAND, password) if password
55
- send_command(SELECT_COMMAND, db) if db
56
- callbacks.each { |block| callback(&block) }
61
+ # Create Redis command methods. Command methods wrap
62
+ # `redis_command()`. This method MUST be called in
63
+ # `initialize()`.
64
+ def create_command_methods!
65
+ REDIS_COMMANDS.each do |command|
66
+ self.class.send(:define_method, command.to_sym) do |*arguments, &block|
67
+ redis_command(command, *arguments, &block)
68
+ end
69
+ end
57
70
  end
58
71
 
59
72
  # Subscribe to a Redis PubSub channel.
60
73
  #
61
74
  # @param channel [String]
75
+ # @yield channel message callback
62
76
  def subscribe(channel, &block)
63
77
  @pubsub_callbacks ||= Hash.new([])
64
78
  @pubsub_callbacks[channel] << block
65
- send_command(SUBSCRIBE_COMMAND, channel, &block)
79
+ redis_command(SUBSCRIBE_COMMAND, channel, &block)
66
80
  end
67
81
 
68
82
  # Unsubscribe to one or more Redis PubSub channels. If a channel
@@ -71,6 +85,7 @@ module Sensu
71
85
  # Redis PubSub channels.
72
86
  #
73
87
  # @param channel [String]
88
+ # @yield unsubscribe callback
74
89
  def unsubscribe(channel=nil, &block)
75
90
  @pubsub_callbacks ||= Hash.new([])
76
91
  arguments = [UNSUBSCRIBE_COMMAND]
@@ -82,7 +97,7 @@ module Sensu
82
97
  @pubsub_callbacks[key] = [block]
83
98
  end
84
99
  end
85
- send_command(arguments)
100
+ redis_command(arguments)
86
101
  end
87
102
  end
88
103
  end
@@ -5,6 +5,8 @@ module Sensu
5
5
  module Redis
6
6
  # Sensu Module connecting to Redis.
7
7
  module Connection
8
+ # Initialize the connection, creating the Redis command methods,
9
+ # and setting the default connection options and callbacks.
8
10
  def initialize(options={})
9
11
  create_command_methods!
10
12
  @host = options[:host]
@@ -22,22 +24,28 @@ module Sensu
22
24
  }
23
25
  end
24
26
 
25
- # Set the on error callback.
27
+ # Set the connection error callback. This callback is called
28
+ # when the connection encounters either a connection, protocol,
29
+ # or command error.
26
30
  def on_error(&block)
27
31
  @error_callback = block
28
32
  end
29
33
 
30
- # Set the before reconnect callback.
34
+ # Set the connection before reconnect callback. This callback is
35
+ # called after the connection closes but before a reconnect is
36
+ # attempted.
31
37
  def before_reconnect(&block)
32
38
  @reconnect_callbacks[:before] = block
33
39
  end
34
40
 
35
- # Set the after reconnect callback.
41
+ # Set the connection after reconnect callback. This callback is
42
+ # called after a successful reconnect, after the connection has
43
+ # been validated.
36
44
  def after_reconnect(&block)
37
45
  @reconnect_callbacks[:after] = block
38
46
  end
39
47
 
40
- # Create an error and pass it to the error callback.
48
+ # Create an error and pass it to the connection error callback.
41
49
  #
42
50
  # @param klass [Class]
43
51
  # @param message [String]
@@ -46,14 +54,14 @@ module Sensu
46
54
  @error_callback.call(redis_error)
47
55
  end
48
56
 
49
- # Determine if connected to Redis.
57
+ # Determine if the connection is connected to Redis.
50
58
  def connected?
51
59
  @connected || false
52
60
  end
53
61
 
54
62
  # Reconnect to Redis. The before reconnect callback is first
55
- # call if not already reconnecting. This method uses a 1 second
56
- # delay before attempting a reconnect.
63
+ # called if not already reconnecting. This method uses a 1
64
+ # second delay before attempting a reconnect.
57
65
  def reconnect!
58
66
  @reconnect_callbacks[:before].call unless @reconnecting
59
67
  @reconnecting = true
@@ -63,18 +71,17 @@ module Sensu
63
71
  end
64
72
 
65
73
  # Close the Redis connection after writing the current
66
- # command/data.
74
+ # Redis command data.
67
75
  def close
68
76
  @closing = true
69
77
  close_connection_after_writing
70
78
  end
71
79
 
72
- # Called by EM when the connection closes, either intentionally
73
- # or unexpectedly.
80
+ # This method is called by EM when the connection closes, either
81
+ # intentionally or unexpectedly. This method is reponsible for
82
+ # starting the reconnect process when appropriate.
74
83
  def unbind
75
84
  @deferred_status = nil
76
- @response_callbacks = []
77
- @multibulk_count = false
78
85
  if @closing
79
86
  @reconnecting = false
80
87
  elsif ((@connected || @reconnecting) && @auto_reconnect) || @reconnect_on_error
@@ -87,25 +94,64 @@ module Sensu
87
94
  @connected = false
88
95
  end
89
96
 
90
- # Validate the connection, ensuring that the Redis release
91
- # supports Sensu's required Redis commands. A connection error
92
- # is thrown if Redis's version does not meet the requirement.
93
- def validate_connection!
94
- info do |redis_info|
97
+ # Authenticate to Redis if a password has been set in the
98
+ # connection options. This method uses `send_command()`
99
+ # directly, as it assumes that the connection has been
100
+ # established. Redis authentication must be done prior to
101
+ # issuing other Redis commands.
102
+ #
103
+ # @yield the callback called once authenticated.
104
+ def authenticate
105
+ if @password
106
+ send_command(AUTH_COMMAND, @password) do |authenticated|
107
+ if authenticated
108
+ yield if block_given?
109
+ else
110
+ error(ConnectionError, "redis authenticate failed")
111
+ end
112
+ end
113
+ else
114
+ yield if block_given?
115
+ end
116
+ end
117
+
118
+ # Select a Redis DB if a DB has been set in the connection
119
+ # options. This method (& Redis command) does not require a
120
+ # response callback.
121
+ def select_db
122
+ send_command(SELECT_COMMAND, @db) if @db
123
+ end
124
+
125
+ # Verify the version of Redis. Redis >= 2.0 RC 1 is required for
126
+ # certain Redis commands that Sensu uses. A connection error is
127
+ # created if the Redis version does not meet the requirements.
128
+ #
129
+ # @yield the callback called once verified.
130
+ def verify_version
131
+ send_command(INFO_COMMAND) do |redis_info|
95
132
  if redis_info[:redis_version] < "1.3.14"
96
133
  error(ConnectionError, "redis version must be >= 2.0 RC 1")
134
+ else
135
+ yield if block_given?
97
136
  end
98
137
  end
99
138
  end
100
139
 
101
- # Called by EM when the connection is established.
140
+ # This method is called by EM when the connection is
141
+ # established. This method is reponsible for validating the
142
+ # connection before Redis commands can be sent.
102
143
  def connection_completed
144
+ @response_callbacks = []
145
+ @multibulk_count = false
103
146
  @connected = true
104
- auth_and_select_db(@password, @db)
105
- validate_connection!
106
- @reconnect_callbacks[:after].call if @reconnecting
107
- @reconnecting = false
108
- succeed
147
+ authenticate do
148
+ select_db
149
+ verify_version do
150
+ succeed
151
+ @reconnect_callbacks[:after].call if @reconnecting
152
+ @reconnecting = false
153
+ end
154
+ end
109
155
  end
110
156
  end
111
157
  end
@@ -51,16 +51,11 @@ module Sensu
51
51
  "incr"
52
52
  ].freeze
53
53
 
54
- # Redis DB select command.
55
- SELECT_COMMAND = "select".freeze
56
-
57
- # Redis authentication command.
54
+ # Redis commands.
58
55
  AUTH_COMMAND = "auth".freeze
59
-
60
- # Redis PubSub subscribe command.
56
+ SELECT_COMMAND = "select".freeze
57
+ INFO_COMMAND = "info".freeze
61
58
  SUBSCRIBE_COMMAND = "subscribe".freeze
62
-
63
- # Redis PubSub unsubscribe command.
64
59
  UNSUBSCRIBE_COMMAND = "unsubscribe".freeze
65
60
 
66
61
  # Boolean Redis response value processor.
@@ -68,6 +63,7 @@ module Sensu
68
63
 
69
64
  # Redis response value processors.
70
65
  RESPONSE_PROCESSORS = {
66
+ "auth" => BOOLEAN_PROCESSOR,
71
67
  "exists" => BOOLEAN_PROCESSOR,
72
68
  "hexists" => BOOLEAN_PROCESSOR,
73
69
  "sismember" => BOOLEAN_PROCESSOR,
data/sensu-redis.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = "sensu-redis"
5
- spec.version = "0.1.4"
5
+ spec.version = "0.1.5"
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.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Porter