sensu-redis 0.1.4 → 0.1.5

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: 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