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 +6 -0
- data/Rakefile +1 -0
- data/beetle.gemspec +2 -2
- data/lib/beetle/publisher.rb +14 -3
- data/lib/beetle/redis_configuration_client.rb +6 -0
- data/lib/beetle/redis_configuration_server.rb +20 -3
- data/test/beetle/redis_configuration_client_test.rb +6 -0
- data/test/beetle/redis_configuration_server_test.rb +9 -1
- data/test/test_helper.rb +12 -1
- metadata +5 -5
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
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.
|
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", ["
|
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"])
|
data/lib/beetle/publisher.rb
CHANGED
@@ -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
|
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
|
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
|
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 =
|
170
|
-
msg = "Received pong message from unknown
|
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
|
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:
|
4
|
+
hash: 27
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.2.
|
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
|
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:
|