beetle 3.5.1 → 3.5.3

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
  SHA256:
3
- metadata.gz: 2dcaf90eaf1b11b7f6350bb34e17d73591616790ede7b43b6e98cef363dd3770
4
- data.tar.gz: 55348c9ce61cc2f43869f9c12cd26bbc5dc033b0e0a0506c0a821d6a6e24862c
3
+ metadata.gz: bce54bf1dc2290bb4c1598f6210b1c292d09691e91df2f67e913747535c90f2d
4
+ data.tar.gz: e6f510fb5b78a7ed0483f713920222ff1959e7a3e3073aac61abed25af56b0bd
5
5
  SHA512:
6
- metadata.gz: 6daabfea72ab76b0fa6944d35cee52139678f9a02a272e86a32af6045750496ee81b96ff685eee1bbe9617030b981df3718b7569efabc98df59f894127da29d1
7
- data.tar.gz: 04d599595b4c39e62a78b496b284a67bed1a545e759d9a094facc757e0334ed16e4bdd7bab4f7bfabb7b6f63da0e590351e86d0da55328ab6db898e9ceaaef7f
6
+ metadata.gz: 8682a1720108f7e95ad9802bcfe5b30283c735cfaa67323e5aca6bca1e1c06d0b6bb58d8fd2b8f4fc1fb7032579832667b78bab0c0f7013a937556650ad14ad7
7
+ data.tar.gz: 255b3fd3827a1f33c1c244967649ab8eaa1adc8f6daa3a111b21e299f1bcc0341f324a1bee3f2c578f5c93b39eeb913caf2c3a6d8ea88d1e89c028c48576e1b0
data/Rakefile CHANGED
@@ -115,18 +115,14 @@ Rake::TestTask.new do |t|
115
115
  t.warning = false
116
116
  end
117
117
 
118
- require 'rdoc/task'
119
-
120
- RDoc::Task.new do |rdoc|
121
- rdoc.rdoc_dir = 'site/rdoc'
122
- rdoc.title = 'Beetle'
123
- rdoc.main = 'README.rdoc'
124
- rdoc.options << '--line-numbers' << '--inline-source' << '--quiet'
125
- rdoc.rdoc_files.include('**/*.rdoc')
126
- rdoc.rdoc_files.include('MIT-LICENSE')
127
- rdoc.rdoc_files.include('lib/**/*.rb')
118
+ task :clean do
119
+ sh "rm -f tmp/*.output tmp/*.log tmp/master-dir/* tmp/slave-dir/* tmp/*lock tmp/*pid test.log" unless ENV['GITHUB_ACTIONS']
128
120
  end
129
121
 
130
- task :clean do
131
- sh "rm -f tmp/*.output tmp/*.log tmp/master-dir/* tmp/slave-dir/* tmp/*lock tmp/*pid test.log"
122
+ require 'yard'
123
+
124
+ YARD::Rake::YardocTask.new do |t|
125
+ OTHER_PATHS = %w()
126
+ t.files = ['lib/**/*.rb'] + OTHER_PATHS
127
+ t.options = %w(--markup-provider=redcarpet --markup=markdown --main=README.md --output-dir=site/yard)
132
128
  end
data/beetle.gemspec CHANGED
@@ -39,8 +39,10 @@ Gem::Specification.new do |s|
39
39
  s.add_development_dependency "mocha", "~> 1.3.0"
40
40
  s.add_development_dependency "mysql2", "~> 0.4.4"
41
41
  s.add_development_dependency "rake", "~> 13.0"
42
- s.add_development_dependency "rdoc", "~> 4.0"
43
42
  s.add_development_dependency "simplecov", "~> 0.15"
44
43
  s.add_development_dependency "webmock", "~> 3.0"
45
44
  s.add_development_dependency "websocket-eventmachine-client"
45
+ s.add_development_dependency 'yard'
46
+ s.add_development_dependency 'redcarpet'
47
+ s.add_development_dependency 'github-markup'
46
48
  end
@@ -17,7 +17,7 @@ Beetle.config.logger.level = Logger::INFO
17
17
  client = Beetle::Client.new
18
18
 
19
19
  # use two servers
20
- Beetle.config.servers = "localhost:5672, localhost:5673"
20
+ Beetle.config.servers = ENV["RABBITMQ_SERVERS"] || "localhost:5672, localhost:5673"
21
21
  # instantiate a client
22
22
  client = Beetle::Client.new
23
23
 
data/examples/rpc.rb CHANGED
@@ -4,7 +4,7 @@ require File.expand_path(File.dirname(__FILE__)+"/../lib/beetle")
4
4
 
5
5
  # suppress debug messages
6
6
  Beetle.config.logger.level = Logger::INFO
7
- Beetle.config.servers = "localhost:5672, localhost:5673"
7
+ Beetle.config.servers = ENV["RABBITMQ_SERVERS"] || "localhost:5672, localhost:5673"
8
8
  # instantiate a client
9
9
 
10
10
  client = Beetle::Client.new
@@ -24,6 +24,26 @@ Feature: Redis auto failover
24
24
  Given a redis server "redis-1" exists as master
25
25
  Then the role of redis server "redis-1" should be "slave"
26
26
 
27
+ Scenario: Successful redis master switch with multiple slaves
28
+ And a redis server "redis-3" exists as slave of "redis-3"
29
+ Given a redis configuration server using redis servers "redis-1,redis-2,redis-3" with clients "rc-client-1,rc-client-2" exists
30
+ And a redis configuration client "rc-client-1" using redis servers "redis-1,redis-2,redis-3" exists
31
+ And a redis configuration client "rc-client-2" using redis servers "redis-1,redis-2,redis-3" exists
32
+ And a beetle handler using the redis-master file from "rc-client-1" exists
33
+ And redis server "redis-1" is down
34
+ And the retry timeout for the redis master check is reached
35
+ Then a system notification for "redis-1" not being available should be sent
36
+ And the role of redis server "redis-2" should be "master"
37
+ And the redis master file of the redis configuration server should contain "redis-2"
38
+ And the redis master of "rc-client-1" should be "redis-2"
39
+ And the redis master of "rc-client-2" should be "redis-2"
40
+ And the redis master of the beetle handler should be "redis-2"
41
+ And a system notification for switching from "redis-1" to "redis-2" should be sent
42
+ Given a redis server "redis-1" exists as master
43
+ Then the role of redis server "redis-1" should be "slave"
44
+ And the redis server "redis-1" is a slave of "redis-2"
45
+ And the redis server "redis-3" is a slave of "redis-2"
46
+
27
47
  Scenario: Successful single redis master switch with multiple failover sets
28
48
  Given a redis server "redis-3" exists as master
29
49
  And a redis server "redis-4" exists as slave of "redis-3"
@@ -1,8 +1,9 @@
1
1
  Given /^consul state has been cleared$/ do
2
+ consul_host = ENV["CONSUL_HOST"] || "localhost:8500"
2
3
  system "killall beetle beetle_handler >/dev/null 2>/dev/null"
3
- system "curl --silent --request PUT http://localhost:8500/v1/kv/apps/beetle/config/ >/dev/null"
4
- system "curl --silent --request PUT http://localhost:8500/v1/kv/shared/config/ >/dev/null"
5
- system "curl --silent --request DELETE http://localhost:8500/v1/kv/apps/beetle/state/redis_master_file_content >/dev/null"
4
+ system "curl --silent --request PUT http://#{consul_host}/v1/kv/apps/beetle/config/ >/dev/null"
5
+ system "curl --silent --request PUT http://#{consul_host}/v1/kv/shared/config/ >/dev/null"
6
+ system "curl --silent --request DELETE http://#{consul_host}/v1/kv/apps/beetle/state/redis_master_file_content >/dev/null"
6
7
  end
7
8
 
8
9
  Given /^a redis server "([^\"]*)" exists as master$/ do |redis_name|
@@ -93,7 +94,6 @@ Given /^an old redis master file for "([^\"]*)" with master "([^\"]*)" exists$/
93
94
  end
94
95
  end
95
96
 
96
-
97
97
  Then /^the role of redis server "([^\"]*)" should be "(master|slave)"$/ do |redis_name, role|
98
98
  expected_role = false
99
99
  10.times do
@@ -103,6 +103,16 @@ Then /^the role of redis server "([^\"]*)" should be "(master|slave)"$/ do |redi
103
103
  assert expected_role, "#{redis_name} is not a #{role}"
104
104
  end
105
105
 
106
+ Then /^the redis server "([^\"]*)" is a slave of "([^\"]*)"$/ do |redis_name, redis_master_name|
107
+ master = TestDaemons::Redis[redis_master_name].redis
108
+ slave = TestDaemons::Redis[redis_name].redis
109
+ 3.times do
110
+ sleep 1
111
+ break if slave.slave_of?(master.host, master.port)
112
+ end
113
+ assert slave.slave_of?(master.host, master.port)
114
+ end
115
+
106
116
  Then /^the redis master of "([^\"]*)" (?:in system "([^"]*)" )?should be "([^\"]*)"$/ do |redis_configuration_client_name, system_name, redis_name|
107
117
  system_name ||= "system"
108
118
  master_file = redis_master_file(redis_configuration_client_name)
@@ -143,11 +153,21 @@ end
143
153
  Then /^the redis master of the beetle handler should be "([^\"]*)"$/ do |redis_name|
144
154
  Beetle.config.servers = "127.0.0.1:5672" # rabbitmq
145
155
  Beetle.config.logger.level = Logger::INFO
146
- client = Beetle::Client.new.configure :auto_delete => true do |config|
147
- config.queue(:echo, :lazy => true, :dead_lettering => true)
148
- config.message(:echo)
156
+ redis_master = TestDaemons::Redis[redis_name].ip_with_port
157
+ response = nil
158
+ expected_response = ['OK', redis_master]
159
+ 3.times do |i|
160
+ client = Beetle::Client.new.configure :auto_delete => true do |config|
161
+ config.queue(:echo, :lazy => true, :dead_lettering => true)
162
+ config.message(:echo)
163
+ end
164
+ t1 = Time.now
165
+ response = client.rpc(:echo, 'echo')
166
+ t2 = Time.now
167
+ # puts "OK,#{redis_master} =?= #{response.join(',')} after #{t2-t1}, attempt #{i+1}"
168
+ break if expected_response == response
149
169
  end
150
- assert_match /#{TestDaemons::Redis[redis_name].ip_with_port}/, client.rpc(:echo, 'nil').second
170
+ assert_equal expected_response, response
151
171
  end
152
172
 
153
173
  Then /^a system notification for "([^\"]*)" not being available should be sent$/ do |redis_name|
@@ -25,9 +25,10 @@ module TestDaemons
25
25
 
26
26
  def self.daemon_controller
27
27
  clients_parameter_string = @@redis_configuration_clients.blank? ? "" : "--client-ids #{@@redis_configuration_clients}"
28
+ consul_host = ENV["CONSUL_HOST"] || "localhost:8500"
28
29
  DaemonController.new(
29
30
  :identifier => "Redis configuration test server",
30
- :start_command => "./beetle configuration_server -v -d --redis-master-file #{redis_master_file} --redis-servers '#{@@redis_servers}' #{clients_parameter_string} --redis-master-retry-interval 1 --pid-file #{pid_file} --log-file #{log_file} --redis-failover-confidence-level #{@@confidence_level} --consul http://localhost:8500",
31
+ :start_command => "./beetle configuration_server -v -d --redis-master-file #{redis_master_file} --redis-servers '#{@@redis_servers}' #{clients_parameter_string} --redis-master-retry-interval 1 --pid-file #{pid_file} --log-file #{log_file} --redis-failover-confidence-level #{@@confidence_level} --consul http://#{consul_host}",
31
32
  :ping_command => lambda{ answers_text_requests? },
32
33
  :pid_file => pid_file,
33
34
  :log_file => log_file,
@@ -34,7 +34,7 @@ module Beetle
34
34
  Bunny::ConnectionError, Bunny::ForcedChannelCloseError, Bunny::ForcedConnectionCloseError,
35
35
  Bunny::MessageError, Bunny::ProtocolError, Bunny::ServerDownError, Bunny::UnsubscribeError,
36
36
  Bunny::AcknowledgementError, Qrack::BufferOverflowError, Qrack::InvalidTypeError,
37
- Errno::EHOSTUNREACH, Errno::ECONNRESET, Timeout::Error
37
+ Errno::EHOSTUNREACH, Errno::ECONNRESET, Errno::ETIMEDOUT, Timeout::Error
38
38
  ]
39
39
  end
40
40
 
@@ -66,6 +66,7 @@ module Beetle
66
66
  logger.debug "Beetle: message sent!"
67
67
  published = 1
68
68
  rescue *bunny_exceptions => e
69
+ logger.warn("Beetle: publishing exception #{e} #{e.backtrace[0..4].join("\n")}")
69
70
  stop!(e)
70
71
  tries -= 1
71
72
  # retry same server on receiving the first exception for it (might have been a normal restart)
@@ -98,6 +99,7 @@ module Beetle
98
99
  published << @server
99
100
  logger.debug "Beetle: message sent (#{published})!"
100
101
  rescue *bunny_exceptions => e
102
+ logger.warn("Beetle: publishing exception #{e} #{e.backtrace[0..4].join("\n")}")
101
103
  stop!(e)
102
104
  retry if (tries += 1) == 1
103
105
  mark_server_dead
@@ -1,3 +1,3 @@
1
1
  module Beetle
2
- VERSION = "3.5.1"
2
+ VERSION = "3.5.3"
3
3
  end
@@ -7,7 +7,7 @@ class AMQPGemBehaviorTest < Minitest::Test
7
7
  begin
8
8
  exception = nil
9
9
  EM.run do
10
- AMQP.start(:logging => false) do |connection|
10
+ AMQP.start(logging: false, host: ENV['RABBITMQ_SERVERS'] || 'localhost') do |connection|
11
11
  EM::Timer.new(1){ connection.close { EM.stop }}
12
12
  channel = AMQP::Channel.new(connection)
13
13
  channel.on_error { puts "woot"}
@@ -26,7 +26,7 @@ module Beetle
26
26
  end
27
27
 
28
28
  test "server should be initialized" do
29
- assert_equal @bs.servers.first, @bs.server
29
+ assert @bs.server
30
30
  end
31
31
 
32
32
  test "current_host should return the hostname of the current server" do
@@ -8,7 +8,7 @@ module Beetle
8
8
  end
9
9
 
10
10
  test "should have a default server" do
11
- assert_equal ["localhost:5672"], @client.servers
11
+ assert !@client.servers.empty?
12
12
  end
13
13
 
14
14
  test "should have no additional subscription servers" do
@@ -87,7 +87,7 @@ module Beetle
87
87
  private
88
88
  def redis_test_master_file(server_string)
89
89
  tmp_dir = File.expand_path("../../../tmp", __FILE__)
90
- Dir.mkdir(tmp_dir) unless File.exists?(tmp_dir)
90
+ Dir.mkdir(tmp_dir) unless File.exist?(tmp_dir)
91
91
  path = tmp_dir + "/redis-master-for-unit-tests"
92
92
  File.open(path, "w"){|f| f.puts server_string}
93
93
  path
@@ -77,7 +77,9 @@ module Beetle
77
77
 
78
78
  class PublisherPublishingTest < Minitest::Test
79
79
  def setup
80
- @client = Client.new
80
+ @config = Configuration.new
81
+ @config.servers = ENV['RABBITMQ_SERVERS'].split(',').first if ENV['RABBITMQ_SERVERS']
82
+ @client = Client.new(@config)
81
83
  @pub = Publisher.new(@client)
82
84
  @pub.stubs(:bind_queues_for_exchange)
83
85
  @client.register_queue("mama", :exchange => "mama-exchange")
@@ -277,6 +279,7 @@ module Beetle
277
279
  class PublisherQueueManagementTest < Minitest::Test
278
280
  def setup
279
281
  @config = Configuration.new
282
+ @config.servers = ENV['RABBITMQ_SERVERS'] if ENV['RABBITMQ_SERVERS']
280
283
  @client = Client.new(@config)
281
284
  @pub = Publisher.new(@client)
282
285
  end
@@ -305,7 +308,9 @@ module Beetle
305
308
  @client.register_queue('test_queue_2', :exchange => 'test_exchange')
306
309
  @client.register_queue('test_queue_3', :exchange => 'test_exchange_2')
307
310
  queue = mock("queue")
308
- queue.expects(:bind).times(3)
311
+ @pub.expects(:bind_queue!).with(queue, "test_exchange", {:key => "test_queue_1"}).once
312
+ @pub.expects(:bind_queue!).with(queue, "test_exchange", {:key => "test_queue_2"}).once
313
+ @pub.expects(:bind_queue!).with(queue, "test_exchange_2", {:key => "test_queue_3"}).once
309
314
  @pub.expects(:declare_queue!).returns(queue).times(3)
310
315
  @pub.send(:bind_queues_for_exchange, 'test_exchange')
311
316
  @pub.send(:bind_queues_for_exchange, 'test_exchange_2')
@@ -315,18 +320,21 @@ module Beetle
315
320
  @client.register_queue('test_queue_1', :exchange => 'test_exchange')
316
321
  @client.register_queue('test_queue_2', :exchange => 'test_exchange')
317
322
  queue = mock("queue")
318
- queue.expects(:bind).twice
319
323
  @pub.expects(:declare_queue!).returns(queue).twice
324
+ @pub.expects(:bind_queue!).with(queue, "test_exchange", {:key => "test_queue_1"}).once
325
+ @pub.expects(:bind_queue!).with(queue, "test_exchange", {:key => "test_queue_2"}).once
320
326
  @pub.send(:bind_queues_for_exchange, 'test_exchange')
321
327
  @pub.send(:bind_queues_for_exchange, 'test_exchange')
322
328
  end
323
329
 
324
330
  test "should declare queues only once even with many bindings" do
331
+
325
332
  @client.register_queue('test_queue', :exchange => 'test_exchange')
326
333
  @client.register_binding('test_queue', :exchange => 'test_exchange', :key => 'sir-message-a-lot')
327
334
  queue = mock("queue")
328
- queue.expects(:bind).twice
329
335
  @pub.expects(:declare_queue!).returns(queue).once
336
+ @pub.expects(:bind_queue!).with(queue, "test_exchange", {:key => "test_queue"}).once
337
+ @pub.expects(:bind_queue!).with(queue, "test_exchange", {:key => "sir-message-a-lot"}).once
330
338
  @pub.send(:bind_queues_for_exchange, 'test_exchange')
331
339
  end
332
340
 
@@ -549,10 +557,11 @@ module Beetle
549
557
  end
550
558
  end
551
559
 
552
-
553
560
  class RPCTest < Minitest::Test
554
561
  def setup
555
- @client = Client.new
562
+ @config = Configuration.new
563
+ @config.servers = ENV['RABBITMQ_SERVERS'].split(',').first if ENV['RABBITMQ_SERVERS']
564
+ @client = Client.new(@config)
556
565
  @pub = Publisher.new(@client)
557
566
  @client.register_message(:test, :exchange => :some_exchange)
558
567
  end
@@ -52,7 +52,9 @@ module Beetle
52
52
 
53
53
  class SubscriberPauseAndResumeTest < Minitest::Test
54
54
  def setup
55
- @client = Client.new
55
+ @config = Configuration.new
56
+ @config.servers = "localhost:5672"
57
+ @client = Client.new(@config)
56
58
  @sub = @client.send(:subscriber)
57
59
  @sub.servers << "localhost:7777"
58
60
  @server1, @server2 = @sub.servers
@@ -342,7 +344,9 @@ module Beetle
342
344
 
343
345
  class SubscriptionTest < Minitest::Test
344
346
  def setup
345
- @client = Client.new
347
+ @config = Configuration.new
348
+ @config.servers = "locahost:5672"
349
+ @client = Client.new(@config)
346
350
  @sub = @client.send(:subscriber)
347
351
  end
348
352
 
data/test/test_helper.rb CHANGED
@@ -27,12 +27,14 @@ end
27
27
  I18n.enforce_available_locales = false
28
28
 
29
29
  Beetle.config.logger = Logger.new(File.dirname(__FILE__) + '/../test.log')
30
- if `docker inspect beetle-redis-master -f '{{.State.Status}}'`.chomp == "running"
31
- Beetle.config.redis_server = "localhost:6370"
32
- Beetle.config.redis_servers = "localhost:6370,localhost:6380"
30
+ Beetle.config.servers = ENV["RABBITMQ_SERVERS"] || "localhost:5672"
31
+
32
+ if system('docker -v >/dev/null') && `docker inspect beetle-redis-master -f '{{.State.Status}}'`.chomp == "running"
33
+ Beetle.config.redis_server = ENV["REDIS_SERVER"] || "localhost:6370"
34
+ Beetle.config.redis_servers = ENV["REDIS_SERVERS"] || "localhost:6370,localhost:6380"
33
35
  else
34
- Beetle.config.redis_server = "localhost:6379"
35
- Beetle.config.redis_servers = "localhost:6379,localhost:6380"
36
+ Beetle.config.redis_server = ENV["REDIS_SERVER"] || "localhost:6379"
37
+ Beetle.config.redis_servers = ENV["REDIS_SERVERS"] || "localhost:6379,localhost:6380"
36
38
  end
37
39
 
38
40
  def header_with_params(opts = {})
@@ -43,7 +45,6 @@ def header_with_params(opts = {})
43
45
  header
44
46
  end
45
47
 
46
-
47
48
  def redis_stub(name, opts = {})
48
49
  default_port = opts['port'] || "1234"
49
50
  default_host = opts['host'] || "foo"
@@ -51,6 +52,6 @@ def redis_stub(name, opts = {})
51
52
  stub(name, opts)
52
53
  end
53
54
 
54
- if `docker inspect beetle-mysql -f '{{.State.Status}}'`.chomp == "running"
55
+ if system('docker -v >/dev/null') && `docker inspect beetle-mysql -f '{{.State.Status}}'`.chomp == "running"
55
56
  ENV['MYSQL_PORT'] = '6612'
56
57
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: beetle
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.5.1
4
+ version: 3.5.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefan Kaes
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2021-06-01 00:00:00.000000000 Z
15
+ date: 2022-02-09 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: bunny
@@ -225,49 +225,77 @@ dependencies:
225
225
  - !ruby/object:Gem::Version
226
226
  version: '13.0'
227
227
  - !ruby/object:Gem::Dependency
228
- name: rdoc
228
+ name: simplecov
229
229
  requirement: !ruby/object:Gem::Requirement
230
230
  requirements:
231
231
  - - "~>"
232
232
  - !ruby/object:Gem::Version
233
- version: '4.0'
233
+ version: '0.15'
234
234
  type: :development
235
235
  prerelease: false
236
236
  version_requirements: !ruby/object:Gem::Requirement
237
237
  requirements:
238
238
  - - "~>"
239
239
  - !ruby/object:Gem::Version
240
- version: '4.0'
240
+ version: '0.15'
241
241
  - !ruby/object:Gem::Dependency
242
- name: simplecov
242
+ name: webmock
243
243
  requirement: !ruby/object:Gem::Requirement
244
244
  requirements:
245
245
  - - "~>"
246
246
  - !ruby/object:Gem::Version
247
- version: '0.15'
247
+ version: '3.0'
248
248
  type: :development
249
249
  prerelease: false
250
250
  version_requirements: !ruby/object:Gem::Requirement
251
251
  requirements:
252
252
  - - "~>"
253
253
  - !ruby/object:Gem::Version
254
- version: '0.15'
254
+ version: '3.0'
255
255
  - !ruby/object:Gem::Dependency
256
- name: webmock
256
+ name: websocket-eventmachine-client
257
257
  requirement: !ruby/object:Gem::Requirement
258
258
  requirements:
259
- - - "~>"
259
+ - - ">="
260
260
  - !ruby/object:Gem::Version
261
- version: '3.0'
261
+ version: '0'
262
262
  type: :development
263
263
  prerelease: false
264
264
  version_requirements: !ruby/object:Gem::Requirement
265
265
  requirements:
266
- - - "~>"
266
+ - - ">="
267
267
  - !ruby/object:Gem::Version
268
- version: '3.0'
268
+ version: '0'
269
269
  - !ruby/object:Gem::Dependency
270
- name: websocket-eventmachine-client
270
+ name: yard
271
+ requirement: !ruby/object:Gem::Requirement
272
+ requirements:
273
+ - - ">="
274
+ - !ruby/object:Gem::Version
275
+ version: '0'
276
+ type: :development
277
+ prerelease: false
278
+ version_requirements: !ruby/object:Gem::Requirement
279
+ requirements:
280
+ - - ">="
281
+ - !ruby/object:Gem::Version
282
+ version: '0'
283
+ - !ruby/object:Gem::Dependency
284
+ name: redcarpet
285
+ requirement: !ruby/object:Gem::Requirement
286
+ requirements:
287
+ - - ">="
288
+ - !ruby/object:Gem::Version
289
+ version: '0'
290
+ type: :development
291
+ prerelease: false
292
+ version_requirements: !ruby/object:Gem::Requirement
293
+ requirements:
294
+ - - ">="
295
+ - !ruby/object:Gem::Version
296
+ version: '0'
297
+ - !ruby/object:Gem::Dependency
298
+ name: github-markup
271
299
  requirement: !ruby/object:Gem::Requirement
272
300
  requirements:
273
301
  - - ">="
@@ -285,19 +313,11 @@ email: opensource@xing.com
285
313
  executables: []
286
314
  extensions: []
287
315
  extra_rdoc_files:
288
- - RELEASE_NOTES.rdoc
289
- - examples/README.rdoc
290
- - REDIS_AUTO_FAILOVER.rdoc
291
- - README.rdoc
292
316
  - MIT-LICENSE
293
317
  files:
294
318
  - MIT-LICENSE
295
- - README.rdoc
296
- - REDIS_AUTO_FAILOVER.rdoc
297
- - RELEASE_NOTES.rdoc
298
319
  - Rakefile
299
320
  - beetle.gemspec
300
- - examples/README.rdoc
301
321
  - examples/attempts.rb
302
322
  - examples/attempts_with_dead_letter_and_exponential_backoff.rb
303
323
  - examples/attempts_with_exponential_backoff.rb
@@ -378,24 +398,24 @@ required_rubygems_version: !ruby/object:Gem::Requirement
378
398
  - !ruby/object:Gem::Version
379
399
  version: 1.3.7
380
400
  requirements: []
381
- rubygems_version: 3.2.16
401
+ rubygems_version: 3.3.4
382
402
  signing_key:
383
403
  specification_version: 3
384
404
  summary: High Availability AMQP Messaging with Redundant Queues
385
405
  test_files:
386
- - test/beetle_test.rb
387
- - test/beetle/client_test.rb
388
406
  - test/beetle/amqp_gem_behavior_test.rb
389
- - test/beetle/deduplication_store_test.rb
390
- - test/beetle/queue_properties_test.rb
391
- - test/beetle/handler_test.rb
407
+ - test/beetle/base_test.rb
392
408
  - test/beetle/beetle_test.rb
409
+ - test/beetle/client_test.rb
393
410
  - test/beetle/configuration_test.rb
394
- - test/beetle/subscriber_test.rb
411
+ - test/beetle/deduplication_store_test.rb
412
+ - test/beetle/handler_test.rb
395
413
  - test/beetle/message/settings_test.rb
396
- - test/beetle/redis_ext_test.rb
397
414
  - test/beetle/message_test.rb
398
415
  - test/beetle/publisher_test.rb
416
+ - test/beetle/queue_properties_test.rb
399
417
  - test/beetle/r_c_test.rb
400
- - test/beetle/base_test.rb
418
+ - test/beetle/redis_ext_test.rb
419
+ - test/beetle/subscriber_test.rb
420
+ - test/beetle_test.rb
401
421
  - test/test_helper.rb
data/README.rdoc DELETED
@@ -1,233 +0,0 @@
1
- = Beetle
2
-
3
- High Availability AMQP Messaging with Redundant Queues
4
-
5
- == About
6
-
7
- Beetle grew out of a project to improve an existing ActiveMQ based messaging
8
- infrastructure. It offers the following features:
9
-
10
- * High Availability (by using multiple message broker instances)
11
- * Redundancy (by replicating queues)
12
- * Simple client API (by encapsulating the publishing/ deduplication logic)
13
-
14
- More information can be found on the {project website}[http://xing.github.com/beetle].
15
-
16
- == Release notes
17
-
18
- See {RELEASE_NOTES.rdoc}[https://github.com/xing/beetle/blob/master/RELEASE_NOTES.rdoc]
19
-
20
- == Usage
21
-
22
- === Configuration
23
- # configure machines
24
-
25
- Beetle.config do |config|
26
- config.servers = "broker1:5672, broker2:5672"
27
- config.redis_server = "redis1:6379"
28
- end
29
-
30
- # instantiate a beetle client
31
-
32
- b = Beetle::Client.new
33
-
34
- # configure exchanges, queues, bindings, messages and handlers
35
-
36
- b.configure do
37
- queue :test
38
- message :test
39
- handler(:test) { |message| puts message.data }
40
- end
41
-
42
- === Publishing
43
- b.publish :test, "I'm a test message"
44
-
45
- === Subscribing
46
- b.listen_queues
47
-
48
- === Examples
49
-
50
- Beetle ships with a number of {example scripts}[http://github.com/xing/beetle/tree/master/examples/].
51
-
52
- The top level Rakefile comes with targets to start several RabbitMQ and redis instances
53
- locally. Make sure the corresponding binaries are in your search path. Open four new shell
54
- windows and execute the following commands:
55
-
56
- rake rabbit:start1
57
- rake rabbit:start2
58
- rake redis:start:master
59
- rake redis:start:slave
60
-
61
- == Prerequisites
62
-
63
- To set up a redundant messaging system you will need
64
- * at least 2 AMQP servers (we use {RabbitMQ}[http://www.rabbitmq.com/])
65
- * at least one {Redis}[http://github.com/antirez/redis] server (better are two in a master/slave setup, see REDIS_AUTO_FAILOVER.rdoc)
66
-
67
- == Test environment
68
-
69
- For testing purposes, you will need a MySQL database with the database
70
- `beetle_test` created. This is needed to test special cases in which
71
- Beetle handles the connection with ActiveRecord:
72
-
73
- mysql -e 'create database beetle_test;'
74
-
75
- You also need a Redis instance running. The default configuration of Redis will work:
76
-
77
- redis-server
78
-
79
- If you want to run the integration tests you need GO installed and you
80
- will need to build the beetle binary. We provide a Makefile for this
81
- purpose, so simply running
82
-
83
- make
84
-
85
- should suffice.
86
-
87
- == Gem Dependencies
88
-
89
- At runtime, Beetle will use
90
- * {bunny}[http://github.com/ruby-amqp/bunny]
91
- * {redis}[http://github.com/redis/redis-rb]
92
- * {amqp}[http://github.com/ruby-amqp/amqp]
93
- (which is based on {eventmachine}[http://github.com/eventmachine/eventmachine])
94
- * {daemons}[http://daemons.rubyforge.org/]
95
- * {activesupport}[https://github.com/rails/rails/tree/master/activesupport]
96
-
97
- For development, you'll need
98
- * {mocha}[http://github.com/floehopper/mocha]
99
- * {cucumber}[http://github.com/aslakhellesoy/cucumber]
100
- * {daemon_controller}[http://github.com/FooBarWidget/daemon_controller]
101
- * {consul}[https://www.consul.io/downloads.html]
102
-
103
- For tests, you'll need
104
- * {activerecord}[https://github.com/rails/rails/tree/master/activerecord]
105
- * {mysql2}[https://github.com/brianmario/mysql2/]
106
-
107
- Dependencies are managed by bundler.
108
-
109
- == Authors
110
-
111
- {Stefan Kaes}[http://github.com/skaes],
112
- {Pascal Friederich}[http://github.com/paukul],
113
- {Ali Jelveh}[http://github.com/dudemeister],
114
- {Bjoern Rochel}[http://github.com/bjro] and
115
- {Sebastian Roebke}[http://github.com/boosty].
116
-
117
- You can find out more about our work on our {dev blog}[http://devblog.xing.com].
118
-
119
- Copyright (c) 2010-2019 {XING AG}[http://www.xing.com/]
120
-
121
- Released under the MIT license. For full details see MIT-LICENSE included in this
122
- distribution.
123
-
124
- == Contributing
125
-
126
- 1. Fork it
127
- 2. Create your feature branch (`git checkout -b my-new-feature`)
128
- 3. Hack along and test your code.
129
- 4. Commit your changes (`git commit -am 'Add some feature'`)
130
- 5. Push to the branch (`git push origin my-new-feature`)
131
- 6. Create new Pull Request
132
-
133
- Don't increase the gem version in your pull requests. It will be done after merging the request,
134
- to allow merging of pull requests in a flexible order.
135
-
136
- == Compiling beetle and running tests
137
-
138
- In order to execute the unit tests, you need Ruby, a running rabbitmq server, a running
139
- redis-server, a running mysql server and a runnning consul server.
140
-
141
- In addition, beetle ships with a cucumber feature to test the automatic redis failover as
142
- an integration test. For this you need a recent Go installation in order to compile the
143
- beetle go binary. Just invoke `make` in the top level directory.
144
-
145
- There are two ways to start the required test dependencies: using `docker-compose` or
146
- starting the services manually.
147
-
148
- === Testing with docker-compose
149
-
150
- Open a separate terminal window and run
151
-
152
- docker-compose pull
153
-
154
- followed by
155
-
156
- docker-compose up
157
-
158
- This will start mysql, two redis servers, two RabbitMQ instances and a single consul
159
- development node.
160
-
161
- Note: make sure to wait until all services are properly started.
162
-
163
-
164
- == Tesing with locally installed services
165
-
166
- The top level Rakefile comes with targets to start several RabbitMQ instances locally.
167
- Make sure the corresponding binaries are in your search path. Open three shell windows and
168
- execute the following command:
169
-
170
- rake rabbit:start1
171
-
172
- and
173
-
174
- rake redis:start:master
175
-
176
- as well as
177
-
178
- rake consul:start
179
-
180
- Then you can run the cucumber feature by running:
181
-
182
- cucumber
183
-
184
- or
185
-
186
- rake cucumber
187
-
188
- Note: Cucumber will automatically run after the unit tests when you run `rake` without
189
- arguments.
190
-
191
-
192
- == How to release a new gem version
193
-
194
- Update RELEASE_NOTES.rdoc!
195
-
196
- We use {semantic versioning}[http://semver.org/] and create a git tag
197
- for each release.
198
-
199
- Edit `lib/beetle/version.rb` and
200
- `go/src/github.com/xing/beetle/version.go` to set the new version
201
- number (`Major.Minor.Patch`).
202
-
203
- In short (see {semver.org}[http://semver.org] for details):
204
-
205
- * *Major* version MUST be incremented if any backwards incompatible changes
206
- are introduced to the public API.
207
- * *Minor* version MUST be incremented if new, backwards compatible functionality
208
- is introduced to the public API. It MUST be incremented if any public API
209
- functionality is marked as deprecated.
210
- * *Patch* version MUST be incremented if only backwards compatible bug fixes
211
- are introduced.
212
-
213
- Then use `rake release` which will create the git tag and upload the
214
- gem to github.com:
215
-
216
- bundle exec rake release
217
-
218
- The generated gem is located in the `pkg/` directory.
219
-
220
- In order to build go binaries and upload the docker container with the
221
- beetle GO binary to docker hub, run
222
-
223
- make release
224
-
225
- This will upload the go binaries to https://github.com/xing/beetle/
226
- and push the beetle container to
227
- https://hub.docker.com/r/xingarchitects/gobeetle/.
228
-
229
- Run
230
-
231
- make tag push TAG=X.X.X
232
-
233
- to tag and push the container with a specific version number.
@@ -1,116 +0,0 @@
1
- = Automatic Redis Failover for Beetle
2
-
3
- == Introduction
4
-
5
- Redis is used as the persistence layer in the AMQP message deduplication
6
- process. Because it is such a critical piece in our infrastructure, it is
7
- essential that a failure of this service is as unlikely as possible. As our
8
- AMQP workers are working in a highly distributed manner, all accessing the same
9
- Redis server, a automatic failover to another Redis server has to be very
10
- defensive and ensure that every worker in the system will switch to the new
11
- server at the same time. If the new server would not get accepted from every
12
- worker, a switch would not be possible. This ensures that even in the case of a
13
- partitioned network it is impossible that two different workers use two
14
- different Redis servers for message deduplication.
15
-
16
- == Our goals
17
-
18
- * opt-in, no need to use the redis-failover solution
19
- * no single point of failure
20
- * automatic switch in case of redis-master failure
21
- * switch should not cause inconsistent data on the redis servers
22
- * workers should be able to determine the current redis-master without asking
23
- another process (as long as the redis servers are working)
24
-
25
- == How it works
26
-
27
- To ensure consistency, a service (the Redis Configuration Server - RCS) is
28
- constantly checking the availability and configuration of the currently
29
- configured Redis master server. If this service detects that the Redis master
30
- is no longer available, it tries to find an alternative server (one of the
31
- slaves) which could be promoted to be the new Redis master.
32
-
33
- On every worker server runs another daemon, the Redis Configuration Client
34
- (RCC) which listens to messages sent by the RCS.
35
-
36
- If the RCS finds another potential Redis Master, it sends out a message to see
37
- if all known RCCs are still available (once again to eliminate the risk of a
38
- partitioned network) and if they agree to the master switch.
39
-
40
- If all RCCs have answered to that message, the RCS sends out a message which
41
- tells the RCCs to invalidate the current master.
42
-
43
- This happens by deleting the contents of a special file which is used
44
- by the workers to store the current Redis master (the content of that file is
45
- the hostname:port of the currently active Redis master). By doing that, it is
46
- ensured that no operations are done to the old Redis master server anymore, because the
47
- AMQP workers check this file's mtime and reads its contents in case that the
48
- file changed, before every Redis operation. When the file has been emptied, the
49
- RCCs respond to the "invalidate" message of the RCS. When all RCCs have
50
- responded, the RCS knows for sure that it is safe to switch the Redis master
51
- now. It sends a "reconfigure" message with the new Redis master hostname:port
52
- to the RCCs, which then write that value into their redis master file.
53
-
54
- Additionally, the RCS sends reconfigure messages with the current Redis master
55
- periodically, to allow new RCCs to pick up the current master. Plus it turns
56
- all other redis servers into slaves of the current master.
57
-
58
- === Prerequisites
59
-
60
- * one redis-configuration-server process ("RCS", on one server), one redis-configuration-client process ("RCC") on every worker server
61
- * the RCS knows about all possible RCCs using a list of client ids
62
- * the RCS and RCCs exchange messages via a "system queue"
63
-
64
- === Flow of actions
65
-
66
- * on startup, an RCC can consult its redis master file to determine the current master without the help of the RCS by checking that it's still a master (or wait for the periodic reconfigure message with the current master from the RCS)
67
- * when the RCS finds the master to be down, it will retry a couple of times before starting a reconfiguration round
68
- * the RCS sends all RCCs a "ping" message to check if every client is there and able to answer
69
- * the RCCs acknowledge via a "pong" message if they can confirm the current master to be unavailable
70
- * the RCS waits for *all* RCCs to reply via pong
71
- * the RCS tells all RCCs to stop using the master by sending an "invalidate" message
72
- * the RCCs acknowledge via an "invalidated" message if they can still confirm the current master to be unavailable
73
- * the RCS waits for *all* RCCs to acknowledge the invalidation
74
- * the RCS promotes the former slave to become the new master (by sending SLAVEOF no one)
75
- * the RCS sends a "reconfigure" message containing the new master to every RCC
76
- * the RCCs write the new master to their redis master file
77
-
78
- === Configuration
79
-
80
- See Beetle::Configuration for setting redis configuration server and client options.
81
-
82
- Please note:
83
- Beetle::Configuration#redis_server must be a file path (not a redis host:port string) to use the redis failover. The RCS and RCCs store the current redis master in that file, and the handlers read from it.
84
-
85
- == How to use it
86
-
87
- This example uses two worker servers, identified by rcc-1 and rcc-2.
88
-
89
- Please note:
90
- All command line options can also be given as a yaml configuration file via the --config-file option.
91
-
92
- === On one server
93
-
94
- Start the Redis Configuration Server:
95
-
96
- beetle configuration_server --redis-servers redis-1:6379,redis-2:6379 --client-ids rcc-1,rcc-2
97
-
98
- Get help for server options:
99
-
100
- beetle configuration_server -h
101
-
102
- === On every worker server
103
-
104
- Start the Redis Configuration Client:
105
-
106
- On first worker server:
107
-
108
- beetle configuration_client --client-id rcc-1
109
-
110
- On second worker server:
111
-
112
- beetle configuration_client --client-id rcc-2
113
-
114
- Get help for client options:
115
-
116
- beetle configuration_client -h
data/RELEASE_NOTES.rdoc DELETED
@@ -1,383 +0,0 @@
1
- = Release Notes
2
-
3
- == Version 3.5.1
4
- * remove blank entries from server list strings
5
- * make sure not to subscribe to any server twice
6
-
7
- == Version 3.5.0
8
- * expose publisher method to setup queues/policies ahead of use
9
-
10
- == Version 3.4.3
11
- * optimize declaration of queues with many bindings
12
-
13
- == Version 3.4.2
14
- * Updated amq-protocol gem to version 2.3.2.
15
- * Fixed a rare race condition on message handler timeouts.
16
-
17
- == Version 3.4.1
18
- * Updated amq-protocol gem to version 2.3.1.
19
-
20
- == Version 3.4.0
21
- * Require redis gem version 4.2.1. This version changes the exists to check for the
22
- existence of multiple keys, return the number of keys in the list that exist. This
23
- requires at least redis gem version 4.2.0, but 4.2.1 contains a bug fix for said
24
- command.
25
-
26
- == Version 3.3.12
27
- * Support queue level declaration of dead letter queue message TTL.
28
-
29
- == Version 3.3.11
30
- * Fixed that dead lettering only works correctly with global config option.
31
-
32
- == Version 3.3.10
33
- * Support configuring RabbitMQ write timeout.
34
-
35
- == Version 3.3.9
36
- * Reduce the number of queue policies created on the servers by allowing
37
- the spefication of a default broker policy. You need to install the
38
- default policy with a priority of zero to match all queues ever
39
- created. This feature is optional.
40
-
41
- == Version 3.3.8
42
- * Avoid needless put call when updating queue policies.
43
- It seems the additional call to get the current definition of a policy
44
- is to be preferred over relying on the idempotency of the PUT call.
45
- This helps when adding a new fresh server to a beetle cluster: import
46
- the definitions of one of the existing nodes on the fresh node before
47
- actually adding it to the list of servers in the client's beetle config..
48
-
49
- == Version 3.3.7
50
- * Increased default http api read timeout to handle large server better.
51
-
52
- == Version 3.3.6
53
- * Fixed a redis connection leak in gobeetle.
54
-
55
- == Version 3.3.5
56
- * Support synchronous queue policy creation.
57
-
58
- == Version 3.3.4
59
- * Track publishing policy options metrics.
60
-
61
- == Version 3.3.3
62
- * Broken.
63
-
64
- == Version 3.3.2
65
- * Changed order of queue policy application to avoid ahead of line blocking in dead letter
66
- queues.
67
-
68
- == Version 3.3.1
69
- * It seems that there is a certain preference on connection level when
70
- selecting the next message to process. We try to protect against
71
- such bias by connecting in random order.
72
-
73
- == Version 3.3.0
74
- * protect against duplicate handler execution by keeping the status of
75
- handler exectution for both redundant and non-redundant messages in
76
- the dedup store for a configurable time window. The config option
77
- is named redis_status_key_expiry_interval. Note that this will
78
- significantly increase the cpu load and memory usage of the Redis
79
- server for applications using a large number of non-redundant
80
- messages. This feature is turned off by default, but we will
81
- activate it with the next major release (4.0.0).
82
-
83
- == Version 3.2.0
84
- * added currently processed message to the handler pre-processing step
85
-
86
- == Version 3.1.0
87
- * added more debug log statements
88
- * added new callbacks on class Beetle::Handler:
89
- * pre_process is called before any message processing commences
90
- * post_process is called after all processing has been completed
91
- these handlers can be used for logging purposes (such as logjam
92
- integration)
93
-
94
- == Version 3.0.0
95
-
96
- * provide client method to setup queues and queue policies.
97
- Setting up queue policies on demand in publisher and subscriber is OK
98
- for a small number of queues, publishers and subscribers. But the HTTP
99
- API of RabbitMQ doesn't scale all that well, so that a large number
100
- of HTTP calls to set up queue policies can in fact crash a server.
101
- * allow queue mode specification and dead lettering specification on a
102
- per queue basis.
103
- * change policy setup to be asynchronous, on demand in publisher and
104
- consumer. Users have to run a processors to listen to messages and
105
- call setup_queue_policies! with the parses JSON paylod of the
106
- message.
107
- * store redis gc stats in redis and display them in the configuration
108
- server web UI
109
- * config server: store current master server in consul, if consul
110
- config has been provided.
111
- * config server: server correctly updates configured client ids when
112
- they change in consul.
113
- * don't create dead letter queues when using the trace functionality
114
- * make sure to clean dedup store when ack_count is larger than 2
115
- * added dump_expiries command to beetle to dump dediplication store
116
- expiry times.
117
- * added delete_queue_keys command to beetle to allow deletion of
118
- excess dedup store entries for a given queue.
119
-
120
- == Version 2.3.2
121
- * config server: fixed a race condition when accessing server state.
122
- HTTP requests run in threads separate from the server dispatcher
123
- thread and thus can cause race conditions/crashes when accessing
124
- server state. Solved this by adding a closure evaluator to the
125
- dispatcher.
126
-
127
- == Version 2.3.1
128
- * updated amqp and amq-protocol requirements in ruby client.
129
- * fixed that a change in consul endpoint was not properly handled by
130
- the beetle configuration client.
131
-
132
- == Version 2.3.0
133
- * redis failover: support multiple redis failover instances. This has
134
- required a change in the redis master file format. The master file
135
- content is now either the old format (host:port) for systems using a
136
- single redis failover system or a mapping from system names to
137
- host:port combinations. For example,
138
- "system1/master1:6379\nsystem2/master" specifies to systems with
139
- their corresponding redis masters. Beetle client uses the configured
140
- system name to tind the master it should use.
141
- * support lazy queues: setting :lazy_quques_enabled on the beetle
142
- cofiguration will enable queue_mode: "lazy" for all queues of
143
- declared on the beetle client.
144
- * improved calculation of channel close an connection disconnect
145
- timeouts for beetle publisher to avoid warnings in RabbitMQ logs.
146
- * use SecureRandom.uuid instead of UUID4R::uuid(4) if UUID4R cannot
147
- be loaded.
148
-
149
- == Version 2.2.4
150
- * redis failover: prevent starting a new master switch while one is running
151
-
152
- == Version 2.2.3
153
- * redis failover: server logs errors when redis oparations fail
154
-
155
- == Version 2.2.2
156
-
157
- * Reset redis configuration server state when master becomes available during
158
- pinging or invalidating. Unlike the former ruby implementation, the go code
159
- continues checking redis availability during pinging or invalidating. However,
160
- the code did not reset state properly, leading the UI to display 'switch in
161
- progress' when in fact there wasn't.
162
-
163
- == Version 2.2.1
164
- * Subscriber exits with meaningful error log on possible authentication failures.
165
-
166
- == Version 2.2.0
167
-
168
- * Support specifying a whitelist of retriable exceptions when registering a
169
- message handler. Exceptions which are not on the list will be regarded as
170
- irrecoverable failures.
171
-
172
- == Version 2.1.2
173
-
174
- * Fixed that redis key GC would never complete when a key scheduled
175
- for GC was deleted by a consumer before the collector could retrieve
176
- its expiry date.
177
- * Fixed tha redis key GC would crash on malformed keys.
178
- * Added method to collect keys specified in a file.
179
-
180
-
181
- == Version 2.1.1
182
-
183
- * Support redis failover with less than 100% acknowlegment from failover clients.
184
-
185
- == Version 2.1.0
186
-
187
- * Support exponential backoff when delaying messages using 'max_delay: int' option.
188
-
189
- == Version 2.0.2
190
-
191
- * fixed incorrect computation of responsiveness threshold in
192
- configuration server
193
-
194
- == Version 2.0.1
195
-
196
- * fix for beetle command not geting stuck when connecting to
197
- configuration server
198
- * configuration server displays last seen times in a human readable format
199
-
200
- == Version 2.0.0
201
-
202
- * beetle command has been rewritten in Go
203
- * garbage collecting redis keys now uses the redis SCAN command
204
-
205
- == Version 1.0.4
206
-
207
- * use amqp protocol version 0.9 by default for publishers
208
-
209
- == Version 1.0.3
210
-
211
- * fixed that publisher did not allow specifying message properties
212
-
213
- == Version 1.0.2
214
-
215
- * relax hiredis requirements to >= 0.4.5
216
-
217
- == Version 1.0.1
218
-
219
- * don't try to connect on publisher shutdown
220
-
221
- == Version 1.0.0
222
-
223
- * introduced semantic versioning
224
- * upgraded gems used for devloping beetle
225
- * upgraded amqp gem to version 1.6.0 and amq-protocol to 2.0.1
226
- * relaxed requirements on redis and hiredis versions
227
- * support setting prefetch count for subscriber
228
-
229
- == Version 0.4.12
230
-
231
- * Don't log warnings when publishing redundantly and only
232
- one server has been configured
233
-
234
- == Version 0.4.11
235
-
236
- * Automatically close open publisher sockets at program exit
237
-
238
- == Version 0.4.10
239
-
240
- * Publisher handles nil and symbols as values in headers correctly
241
-
242
- == Version 0.4.9
243
-
244
- * Allow redis_configuration_client to run in the foreground (useful
245
- for docker)
246
-
247
- == Version 0.4.8
248
-
249
- * unseen clients need to be an array
250
-
251
- == Version 0.4.7
252
-
253
- * list clients which have never sent a ping in the failover server UI
254
-
255
- == Version 0.4.6
256
-
257
- * Publish activesupport notifications to support performance measurements
258
-
259
- == Version 0.4.5
260
-
261
- * Starting mutliple redis failover clients is now prohibited by
262
- default. This behavior can be overriden using
263
- "beetle configuration_client start -- --multiple"
264
-
265
- == Version 0.4.4
266
-
267
- * added command to show beetle version: "beetle --version"
268
- * configuration server tracks ids of unknown clients
269
- * configuration clients now sends heartbeats
270
- * configuration server tracks last seen times of clients, based on heartbeat
271
-
272
- == Version 0.4.3
273
-
274
- * fixed a race condition which could lead to duplicate message processing
275
- * fixed eventmachine shutdown sequence problem, which led to ACKs
276
- occasionally being lost due to writing to a closed socket, which in
277
- turn caused messages to be processed twice
278
- * stop_listening now always triggers the subscribe shutdown sequence
279
- via a eventmachine timer callback, if the eventmachine reactor is running
280
-
281
- == Version 0.4.2
282
-
283
- * Fail hard on missing master file
284
- * Set message timestamp header
285
-
286
- == Version 0.4.1
287
-
288
- * Require newer bunny version (0.7.10) to fix publishing of messages larger than frame_max
289
-
290
- == Version 0.4.0
291
-
292
- * Added optional dead lettering feature to mimic RabbitMQ 2.x requeueing behaviour on RabbitMQ 3.x
293
-
294
- == Version 0.3.14
295
-
296
- * switched message id generation to use v4 uuids
297
-
298
- == Version 0.3.0
299
-
300
- * redis master file contents now correctly reflects the state of the running configuration server
301
- * allow accelerating master switch via POST to redis configuration server
302
- * embedded http server into the redis configuration server (port 8080)
303
- * fixed a problem with redis shutdown command
304
- * upgraded to redis 2.2.2
305
- * upgraded to amqp gem version 0.8 line
306
- * use hiredis as the redis backend, which overcomes lack of proper time-outs in the "generic" redis-rb
307
- gem for Ruby 1.9
308
- * use fully qualified hostnames to identify redis configuration clients
309
-
310
- == Version 0.2.9.8
311
-
312
- * since version 2.0, RabbitMQ supports Basic.reject(:requeue => true). we use it now too,
313
- because it enhances performance of message processors. this means of course, you can
314
- only use beetle gem versions >= 0.2.9.8 if your rabbitmq brokers are at least version 2.0.
315
- * publishing timeout defaults to 0 to avoid extreme message loss in some cases
316
-
317
-
318
- == Version 0.2.9.7
319
-
320
- * use new bunny_ext gem and allow specification of global publishing timeouts
321
- * registering a message now automatically registers the corresponding exchange
322
- * don't try to bind queues for an exchange hich has no queue
323
- * ruby 1.9.2 compatibility fixes
324
-
325
- == Version 0.2.9
326
-
327
- * Beetle::Client now raises an exception when it fails to publish a message to at least 1 RabbitMQ server
328
- * Subscribers are now stopped cleanly to avoid 'closed abruptly' messages in the RabbitMQ server log
329
-
330
- == Version 0.2.6
331
-
332
- * Set dependency on ActiveSupport to 2.3.x since it ain't compatible to version 3.x yet
333
- * Publishers catch a wider range (all?) of possible exceptions when publishing messages
334
- * Redis Configuration Servers detect and warn when unknown Redis Configuration Clients connect
335
-
336
- == Version 0.2.5
337
-
338
- Added missing files to gem and rdoc
339
-
340
- == Version 0.2.4
341
-
342
- Log and send a system notification when pong message from unknown client received.
343
-
344
- == Version 0.2.2
345
-
346
- Patch release which upgrades to redis-rb 2.0.4. This enables us to drop our redis monkey
347
- patch which enabled connection timeouts for earlier redis versions. Note that earlier
348
- Beetle versions are not compatible with redis 2.0.4.
349
-
350
- == Version 0.2.1
351
-
352
- Improved error message when no rabbitmq broker is available.
353
-
354
- == Version 0.2
355
-
356
- This version adds support for automatic redis deduplication store failover (see separate
357
- file REDIS_AUTO_FAILOVER.rdoc).
358
-
359
- === User visible changes
360
-
361
- * it's possible to register auto deleted queues and exchanges
362
- * Beetle::Client#configure returns self in order to simplify client setup
363
- * it's possible to trace specific messages (see Beetle::Client#trace)
364
- * default message handler timeout is 10 minutes now
365
- * system wide configuration values can be specified via a yml formatted configuration
366
- file (Beetle::Configuration#config_file)
367
- * the config value redis_server specifies either a single server or a file path (used
368
- by the automatic redis failover logic)
369
-
370
- === Fugs Bixed
371
-
372
- * handle active_support seconds notation for handler timeouts correctly
373
- * error handler was erroneously called for expired messages
374
- * subscribers would block when some non beetle process posts an undecodable message
375
-
376
- === Gem Dependency Changes
377
-
378
- * redis needs to be at least version 2.0.3
379
- * we make use of the SystemTimer gem for ruby 1.8.7
380
-
381
- == Version 0.1
382
-
383
- Initial Release
data/examples/README.rdoc DELETED
@@ -1,12 +0,0 @@
1
- === Examples
2
-
3
- Beetle ships with a number of {example scripts}[http://github.com/xing/beetle/tree/master/examples/].
4
-
5
- The top level Rakefile comes with targets to start several RabbitMQ and redis instances
6
- locally. Make sure the corresponding binaries are in your search path. Open four new shell
7
- windows and execute the following commands:
8
-
9
- rake rabbit:start1
10
- rake rabbit:start2
11
- rake redis:start:master
12
- rake redis:start:slave