beetle 0.2.3 → 0.2.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.
- data/MIT-LICENSE +20 -0
- data/REDIS_AUTO_FAILOVER.rdoc +124 -0
- data/RELEASE_NOTES.rdoc +50 -0
- data/Rakefile +113 -0
- data/beetle.gemspec +3 -3
- data/features/README.rdoc +23 -0
- data/features/redis_auto_failover.feature +105 -0
- data/features/step_definitions/redis_auto_failover_steps.rb +133 -0
- data/features/support/beetle_handler +32 -0
- data/features/support/env.rb +48 -0
- data/features/support/system_notification_logger +31 -0
- data/features/support/test_daemons/redis.conf.erb +189 -0
- data/features/support/test_daemons/redis.rb +186 -0
- data/features/support/test_daemons/redis_configuration_client.rb +64 -0
- data/features/support/test_daemons/redis_configuration_server.rb +52 -0
- data/lib/beetle/redis_configuration_server.rb +10 -0
- data/script/console +28 -0
- data/script/start_rabbit +29 -0
- data/test/beetle/deduplication_store_test.rb +3 -1
- data/test/beetle/redis_configuration_server_test.rb +18 -0
- metadata +25 -4
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'daemon_controller'
|
2
|
+
|
3
|
+
module TestDaemons
|
4
|
+
class RedisConfigurationClient
|
5
|
+
cattr_reader :instances
|
6
|
+
@@next_daemon_id = 0
|
7
|
+
@@instances = {}
|
8
|
+
|
9
|
+
def initialize(name)
|
10
|
+
@name = name
|
11
|
+
@daemon_id = @@next_daemon_id
|
12
|
+
|
13
|
+
@@next_daemon_id += 1
|
14
|
+
@@instances[name] = self
|
15
|
+
end
|
16
|
+
|
17
|
+
class << self
|
18
|
+
def find_or_initialize_by_name(name)
|
19
|
+
@@instances[name] ||= new(name)
|
20
|
+
end
|
21
|
+
alias_method :[], :find_or_initialize_by_name
|
22
|
+
|
23
|
+
def stop_all
|
24
|
+
@@instances.values.each{|i| i.stop}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def start
|
29
|
+
daemon_controller.start
|
30
|
+
end
|
31
|
+
|
32
|
+
def stop
|
33
|
+
daemon_controller.stop
|
34
|
+
end
|
35
|
+
|
36
|
+
def daemon_controller
|
37
|
+
@daemon_controller ||= DaemonController.new(
|
38
|
+
:identifier => "Redis configuration test client",
|
39
|
+
:start_command => "ruby bin/beetle configuration_client start -- -v --redis-master-file #{redis_master_file} --id #{@name} --pid-dir #{tmp_path} --amqp-servers 127.0.0.1:5672",
|
40
|
+
:ping_command => lambda{ true },
|
41
|
+
:pid_file => pid_file,
|
42
|
+
:log_file => log_file,
|
43
|
+
:start_timeout => 5
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
47
|
+
def redis_master_file
|
48
|
+
"#{tmp_path}/redis-master-#{@name}"
|
49
|
+
end
|
50
|
+
|
51
|
+
def pid_file
|
52
|
+
"#{tmp_path}/redis_configuration_client#{@daemon_id}.pid"
|
53
|
+
end
|
54
|
+
|
55
|
+
def log_file
|
56
|
+
"#{tmp_path}/redis_configuration_client.output"
|
57
|
+
end
|
58
|
+
|
59
|
+
def tmp_path
|
60
|
+
File.expand_path(File.dirname(__FILE__) + "/../../../tmp")
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'daemon_controller'
|
2
|
+
|
3
|
+
module TestDaemons
|
4
|
+
class RedisConfigurationServer
|
5
|
+
|
6
|
+
# At the moment, we need only one, so we implement the methods
|
7
|
+
# as class methods
|
8
|
+
|
9
|
+
@@redis_servers = ""
|
10
|
+
@@redis_configuration_clients = ""
|
11
|
+
|
12
|
+
def self.start(redis_servers, redis_configuration_clients)
|
13
|
+
stop
|
14
|
+
@@redis_servers = redis_servers
|
15
|
+
@@redis_configuration_clients = redis_configuration_clients
|
16
|
+
daemon_controller.start
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.stop
|
20
|
+
daemon_controller.stop
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.daemon_controller
|
24
|
+
clients_parameter_string = @@redis_configuration_clients.blank? ? "" : "--client-ids #{@@redis_configuration_clients}"
|
25
|
+
DaemonController.new(
|
26
|
+
:identifier => "Redis configuration test server",
|
27
|
+
:start_command => "ruby bin/beetle configuration_server start -- -v --redis-master-file #{redis_master_file} --redis-servers #{@@redis_servers} #{clients_parameter_string} --redis-retry-interval 1 --pid-dir #{tmp_path} --amqp-servers 127.0.0.1:5672",
|
28
|
+
:ping_command => lambda{ true },
|
29
|
+
:pid_file => pid_file,
|
30
|
+
:log_file => log_file,
|
31
|
+
:start_timeout => 5
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.redis_master_file
|
36
|
+
"#{tmp_path}/redis-master-rc-server"
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.pid_file
|
40
|
+
"#{tmp_path}/redis_configuration_server.pid"
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.log_file
|
44
|
+
"#{tmp_path}/redis_configuration_server.output"
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.tmp_path
|
48
|
+
File.expand_path(File.dirname(__FILE__) + "/../../../tmp")
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
@@ -64,6 +64,7 @@ module Beetle
|
|
64
64
|
def pong(payload)
|
65
65
|
id = payload["id"]
|
66
66
|
token = payload["token"]
|
67
|
+
return unless validate_pong_client_id(id)
|
67
68
|
logger.info "Received pong message from id '#{id}' with token '#{token}'"
|
68
69
|
return unless redeem_token(token)
|
69
70
|
@client_pong_ids_received << id
|
@@ -164,6 +165,15 @@ module Beetle
|
|
164
165
|
redis.unknowns.include?(current_master) ? redis.slaves_of(current_master).first : current_master
|
165
166
|
end
|
166
167
|
|
168
|
+
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}'"
|
171
|
+
logger.error(msg)
|
172
|
+
beetle.publish(:system_notification, {"message" => msg}.to_json)
|
173
|
+
end
|
174
|
+
known_client
|
175
|
+
end
|
176
|
+
|
167
177
|
def redeem_token(token)
|
168
178
|
valid_token = token == @current_token
|
169
179
|
logger.info "Ignored message (token was '#{token.inspect}', but expected '#{@current_token.inspect}')" unless valid_token
|
data/script/console
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'optparse'
|
4
|
+
|
5
|
+
options = { }
|
6
|
+
OptionParser.new do |opt|
|
7
|
+
opt.banner = "Usage: console [options]"
|
8
|
+
opt.on("--debugger", 'Enable ruby-debugging for the console.') { |v| options[:debugger] = v }
|
9
|
+
opt.parse!(ARGV)
|
10
|
+
end
|
11
|
+
|
12
|
+
libs = " -r irb/completion"
|
13
|
+
libs << %( -r ubygems)
|
14
|
+
libs << %( -r #{File.expand_path("../../lib/beetle.rb",__FILE__)})
|
15
|
+
|
16
|
+
if options[:debugger]
|
17
|
+
begin
|
18
|
+
require 'ruby-debug'
|
19
|
+
libs << " -r ruby-debug"
|
20
|
+
puts "=> Debugger enabled"
|
21
|
+
rescue Exception
|
22
|
+
puts "You need to install ruby-debug to run the console in debugging mode. With gems, use 'gem install ruby-debug'"
|
23
|
+
exit
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
|
28
|
+
exec "#{irb} #{libs} --simple-prompt"
|
data/script/start_rabbit
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
# export RABBITMQ_MNESIA_BASE=/var/lib/rabbitmq/mnesia2
|
4
|
+
# Defaults to /var/lib/rabbitmq/mnesia. Set this to the directory where Mnesia
|
5
|
+
# database files should be placed.
|
6
|
+
|
7
|
+
# export RABBITMQ_LOG_BASE
|
8
|
+
# Defaults to /var/log/rabbitmq. Log files generated by the server will be placed
|
9
|
+
# in this directory.
|
10
|
+
|
11
|
+
export RABBITMQ_NODENAME=$1
|
12
|
+
# Defaults to rabbit. This can be useful if you want to run more than one node
|
13
|
+
# per machine - RABBITMQ_NODENAME should be unique per erlang-node-and-machine
|
14
|
+
# combination. See clustering on a single machine guide at <http://www.rab-
|
15
|
+
# bitmq.com/clustering.html#single-machine> for details.
|
16
|
+
|
17
|
+
# RABBITMQ_NODE_IP_ADDRESS
|
18
|
+
# Defaults to 0.0.0.0. This can be changed if you only want to bind to one net-
|
19
|
+
# work interface.
|
20
|
+
|
21
|
+
export RABBITMQ_NODE_PORT=$2
|
22
|
+
# Defaults to 5672.
|
23
|
+
|
24
|
+
# RABBITMQ_CLUSTER_CONFIG_FILE
|
25
|
+
# Defaults to /etc/rabbitmq/rabbitmq_cluster.config. If this file is present it
|
26
|
+
# is used by the server to auto-configure a RabbitMQ cluster. See the clustering
|
27
|
+
# guide at <http://www.rabbitmq.com/clustering.html> for details.
|
28
|
+
|
29
|
+
rabbitmq-server
|
@@ -73,7 +73,9 @@ module Beetle
|
|
73
73
|
|
74
74
|
private
|
75
75
|
def redis_test_master_file(server_string)
|
76
|
-
|
76
|
+
tmp_dir = File.expand_path("../../../tmp", __FILE__)
|
77
|
+
Dir.mkdir(tmp_dir) unless File.exists?(tmp_dir)
|
78
|
+
path = tmp_dir + "/redis-master-for-unit-tests"
|
77
79
|
File.open(path, "w"){|f| f.puts server_string}
|
78
80
|
path
|
79
81
|
end
|
@@ -275,4 +275,22 @@ module Beetle
|
|
275
275
|
info
|
276
276
|
end
|
277
277
|
end
|
278
|
+
|
279
|
+
class RedisConfigurationServerSystemNotificationAndLoggingTest < Test::Unit::TestCase
|
280
|
+
def setup
|
281
|
+
Beetle.config.redis_configuration_client_ids = "rc-client-1,rc-client-2"
|
282
|
+
@server = RedisConfigurationServer.new
|
283
|
+
@server.stubs(:beetle).returns(stub(:publish))
|
284
|
+
@server.stubs(:logger).returns(stub)
|
285
|
+
EventMachine.stubs(:add_timer).yields
|
286
|
+
end
|
287
|
+
|
288
|
+
test "should log and send a system notification when pong message from unknown client received" do
|
289
|
+
payload = {"id" => "unknown-client", "token" => @server.current_token}
|
290
|
+
msg = "Received pong message from unknown client 'unknown-client'"
|
291
|
+
@server.beetle.expects(:publish).with(:system_notification, ({:message => msg}).to_json)
|
292
|
+
@server.logger.expects(:error).with(msg)
|
293
|
+
@server.pong(payload)
|
294
|
+
end
|
295
|
+
end
|
278
296
|
end
|
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: 29
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.2.
|
9
|
+
- 5
|
10
|
+
version: 0.2.5
|
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-
|
21
|
+
date: 2010-08-23 00:00:00 +02:00
|
22
22
|
default_executable: beetle
|
23
23
|
dependencies:
|
24
24
|
- !ruby/object:Gem::Dependency
|
@@ -182,7 +182,12 @@ executables:
|
|
182
182
|
extensions:
|
183
183
|
- ext/mkrf_conf.rb
|
184
184
|
extra_rdoc_files:
|
185
|
+
- examples/README.rdoc
|
186
|
+
- features/README.rdoc
|
185
187
|
- README.rdoc
|
188
|
+
- REDIS_AUTO_FAILOVER.rdoc
|
189
|
+
- RELEASE_NOTES.rdoc
|
190
|
+
- MIT-LICENSE
|
186
191
|
files:
|
187
192
|
- examples/attempts.rb
|
188
193
|
- examples/handler_class.rb
|
@@ -212,9 +217,25 @@ files:
|
|
212
217
|
- lib/beetle/redis_server_info.rb
|
213
218
|
- lib/beetle/subscriber.rb
|
214
219
|
- lib/beetle.rb
|
220
|
+
- features/README.rdoc
|
221
|
+
- features/redis_auto_failover.feature
|
222
|
+
- features/step_definitions/redis_auto_failover_steps.rb
|
223
|
+
- features/support/beetle_handler
|
224
|
+
- features/support/env.rb
|
225
|
+
- features/support/system_notification_logger
|
226
|
+
- features/support/test_daemons/redis.conf.erb
|
227
|
+
- features/support/test_daemons/redis.rb
|
228
|
+
- features/support/test_daemons/redis_configuration_client.rb
|
229
|
+
- features/support/test_daemons/redis_configuration_server.rb
|
230
|
+
- script/console
|
231
|
+
- script/start_rabbit
|
215
232
|
- beetle.gemspec
|
233
|
+
- Rakefile
|
216
234
|
- examples/README.rdoc
|
217
235
|
- README.rdoc
|
236
|
+
- REDIS_AUTO_FAILOVER.rdoc
|
237
|
+
- RELEASE_NOTES.rdoc
|
238
|
+
- MIT-LICENSE
|
218
239
|
- test/beetle/base_test.rb
|
219
240
|
- test/beetle/client_test.rb
|
220
241
|
- test/beetle/configuration_test.rb
|