beetle 0.2.5 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
data/RELEASE_NOTES.rdoc CHANGED
@@ -1,5 +1,11 @@
1
1
  = Release Notes
2
2
 
3
+ == Version 0.2.6
4
+
5
+ * Set dependency on ActiveSupport to 2.3.x since it ain't compatible to version 3.x yet
6
+ * Publishers catch a wider range (all?) of possible exceptions when publishing messages
7
+ * Redis Configuration Servers detect and warn when unknown Redis Configuration Clients connect
8
+
3
9
  == Version 0.2.5
4
10
 
5
11
  Added missing files to gem and rdoc
data/Rakefile CHANGED
@@ -2,6 +2,7 @@ require 'rake'
2
2
  require 'rake/testtask'
3
3
  require 'rcov/rcovtask'
4
4
  require 'cucumber/rake/task'
5
+ require 'active_support'
5
6
 
6
7
  # 1.8/1.9 compatible way of loading lib/beetle.rb
7
8
  $:.unshift 'lib'
data/beetle.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "beetle"
3
- s.version = "0.2.5"
3
+ s.version = "0.2.6"
4
4
 
5
5
  s.required_rubygems_version = ">= 1.3.1"
6
6
  s.authors = ["Stefan Kaes", "Pascal Friederich", "Ali Jelveh", "Sebastian Roebke"]
@@ -33,7 +33,7 @@ Gem::Specification.new do |s|
33
33
  s.add_runtime_dependency("bunny", [">= 0.6.0"])
34
34
  s.add_runtime_dependency("redis", [">= 2.0.4"])
35
35
  s.add_runtime_dependency("amqp", [">= 0.6.7"])
36
- s.add_runtime_dependency("activesupport", [">= 2.3.4"])
36
+ s.add_runtime_dependency("activesupport", ["~> 2.3.4"])
37
37
  s.add_runtime_dependency("daemons", [">= 1.0.10"])
38
38
  s.add_development_dependency("mocha", [">= 0"])
39
39
  s.add_development_dependency("rcov", [">= 0"])
@@ -9,6 +9,17 @@ module Beetle
9
9
  @bunnies = {}
10
10
  end
11
11
 
12
+ # list of exceptions potentially raised by bunny
13
+ # these need to be lazy, because qrack exceptions are only defined after a connection has been established
14
+ def bunny_exceptions
15
+ [
16
+ Bunny::ConnectionError, Bunny::ForcedChannelCloseError, Bunny::ForcedConnectionCloseError,
17
+ Bunny::MessageError, Bunny::ProtocolError, Bunny::ServerDownError, Bunny::UnsubscribeError,
18
+ Bunny::AcknowledgementError, Qrack::BufferOverflowError, Qrack::InvalidTypeError,
19
+ Errno::EHOSTUNREACH, Errno::ECONNRESET
20
+ ]
21
+ end
22
+
12
23
  def publish(message_name, data, opts={}) #:nodoc:
13
24
  opts = @client.messages[message_name].merge(opts.symbolize_keys)
14
25
  exchange_name = opts.delete(:exchange)
@@ -33,7 +44,7 @@ module Beetle
33
44
  exchange(exchange_name).publish(data, opts)
34
45
  logger.debug "Beetle: message sent!"
35
46
  published = 1
36
- rescue Bunny::ServerDownError, Bunny::ConnectionError
47
+ rescue *bunny_exceptions
37
48
  stop!
38
49
  mark_server_dead
39
50
  tries -= 1
@@ -60,7 +71,7 @@ module Beetle
60
71
  exchange(exchange_name).publish(data, opts)
61
72
  published << @server
62
73
  logger.debug "Beetle: message sent (#{published})!"
63
- rescue Bunny::ServerDownError, Bunny::ConnectionError
74
+ rescue *bunny_exceptions
64
75
  stop!
65
76
  mark_server_dead
66
77
  end
@@ -101,7 +112,7 @@ module Beetle
101
112
  status = msg[:header].properties[:headers][:status]
102
113
  end
103
114
  logger.debug "Beetle: rpc complete!"
104
- rescue Bunny::ServerDownError, Bunny::ConnectionError
115
+ rescue *bunny_exceptions
105
116
  stop!
106
117
  mark_server_dead
107
118
  tries -= 1
@@ -37,6 +37,7 @@ module Beetle
37
37
  # loop, reacting to failover related messages sent by RedisConfigurationServer.
38
38
  def start
39
39
  verify_redis_master_file_string
40
+ client_started!
40
41
  logger.info "RedisConfigurationClient starting (client id: #{id})"
41
42
  determine_initial_master
42
43
  clear_redis_master_file unless current_master.try(:master?)
@@ -102,6 +103,7 @@ module Beetle
102
103
  config.message :client_invalidated
103
104
  config.message :reconfigure
104
105
  config.queue :reconfigure, :amqp_name => "#{system}_reconfigure_#{id}"
106
+ config.message :client_started
105
107
 
106
108
  config.handler [:ping, :invalidate, :reconfigure], MessageDispatcher
107
109
  end
@@ -118,6 +120,10 @@ module Beetle
118
120
  beetle.publish(:pong, {"id" => id, "token" => @current_token}.to_json)
119
121
  end
120
122
 
123
+ def client_started!
124
+ beetle.publish(:client_started, {"id" => id}.to_json)
125
+ end
126
+
121
127
  def invalidate!
122
128
  @current_master = nil
123
129
  clear_redis_master_file
@@ -75,6 +75,17 @@ module Beetle
75
75
  end
76
76
  end
77
77
 
78
+ def client_started(payload)
79
+ id = payload["id"]
80
+ if client_id_valid?(id)
81
+ logger.info("Received client_started message from id #{id}")
82
+ else
83
+ msg = "Received client_started message from unknown id '#{id}'"
84
+ logger.error(msg)
85
+ beetle.publish(:system_notification, {"message" => msg}.to_json)
86
+ end
87
+ end
88
+
78
89
  # called by the message dispatcher when a "client_invalidated" message from a RedisConfigurationClient is received
79
90
  def client_invalidated(payload)
80
91
  id = payload["id"]
@@ -139,8 +150,10 @@ module Beetle
139
150
  config.message :invalidate
140
151
  config.message :reconfigure
141
152
  config.message :system_notification
153
+ config.message :client_started
154
+ config.queue :client_started, :amqp_name => "#{system}_client_started"
142
155
 
143
- config.handler [:pong, :client_invalidated], MessageDispatcher
156
+ config.handler [:pong, :client_invalidated, :client_started], MessageDispatcher
144
157
  end
145
158
  end
146
159
 
@@ -166,13 +179,17 @@ module Beetle
166
179
  end
167
180
 
168
181
  def validate_pong_client_id(client_id)
169
- unless known_client = @client_ids.include?(client_id)
170
- msg = "Received pong message from unknown client '#{client_id}'"
182
+ unless known_client = client_id_valid?(client_id)
183
+ msg = "Received pong message from unknown id '#{client_id}'"
171
184
  logger.error(msg)
172
185
  beetle.publish(:system_notification, {"message" => msg}.to_json)
173
186
  end
174
187
  known_client
175
188
  end
189
+
190
+ def client_id_valid?(client_id)
191
+ @client_ids.include?(client_id)
192
+ end
176
193
 
177
194
  def redeem_token(token)
178
195
  valid_token = token == @current_token
@@ -10,6 +10,12 @@ module Beetle
10
10
  @client.stubs(:verify_redis_master_file_string)
11
11
  end
12
12
 
13
+ test "should send a client_started message when started" do
14
+ @client.stubs(:clear_redis_master_file)
15
+ @client.beetle.expects(:publish).with(:client_started, {:id => @client.id}.to_json)
16
+ @client.start
17
+ end
18
+
13
19
  test "config should return the beetle config" do
14
20
  assert_equal Beetle.config, @client.config
15
21
  end
@@ -287,10 +287,18 @@ module Beetle
287
287
 
288
288
  test "should log and send a system notification when pong message from unknown client received" do
289
289
  payload = {"id" => "unknown-client", "token" => @server.current_token}
290
- msg = "Received pong message from unknown client 'unknown-client'"
290
+ msg = "Received pong message from unknown id 'unknown-client'"
291
291
  @server.beetle.expects(:publish).with(:system_notification, ({:message => msg}).to_json)
292
292
  @server.logger.expects(:error).with(msg)
293
293
  @server.pong(payload)
294
294
  end
295
+
296
+ test "should warn about unknown clients when receiving client_started messages" do
297
+ payload = {"id" => "unknown-client"}
298
+ msg = "Received client_started message from unknown id 'unknown-client'"
299
+ @server.beetle.expects(:publish).with(:system_notification, ({:message => msg}).to_json)
300
+ @server.logger.expects(:error).with(msg)
301
+ @server.client_started(payload)
302
+ end
295
303
  end
296
304
  end
data/test/test_helper.rb CHANGED
@@ -3,9 +3,20 @@ require 'active_support'
3
3
  require 'active_support/testing/declarative'
4
4
  require 'test/unit'
5
5
  begin
6
- require 'redgreen' unless ENV['TM_FILENAME']
6
+ require 'redgreen' unless ENV['TM_FILENAME']
7
7
  rescue MissingSourceFile
8
8
  end
9
+
10
+ # we can remove this hack which is needed only for testing
11
+ begin
12
+ require 'qrack/errors'
13
+ rescue LoadError
14
+ module Qrack
15
+ class BufferOverflowError < StandardError; end
16
+ class InvalidTypeError < StandardError; end
17
+ end
18
+ end
19
+
9
20
  require 'mocha'
10
21
  require File.expand_path(File.dirname(__FILE__) + '/../lib/beetle')
11
22
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: beetle
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 27
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 5
10
- version: 0.2.5
9
+ - 6
10
+ version: 0.2.6
11
11
  platform: ruby
12
12
  authors:
13
13
  - Stefan Kaes
@@ -18,7 +18,7 @@ autorequire:
18
18
  bindir: bin
19
19
  cert_chain: []
20
20
 
21
- date: 2010-08-23 00:00:00 +02:00
21
+ date: 2010-09-08 00:00:00 +02:00
22
22
  default_executable: beetle
23
23
  dependencies:
24
24
  - !ruby/object:Gem::Dependency
@@ -91,7 +91,7 @@ dependencies:
91
91
  requirement: &id005 !ruby/object:Gem::Requirement
92
92
  none: false
93
93
  requirements:
94
- - - ">="
94
+ - - ~>
95
95
  - !ruby/object:Gem::Version
96
96
  hash: 11
97
97
  segments: