beetle 3.3.6 → 3.3.11
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 +4 -4
- data/README.rdoc +1 -1
- data/RELEASE_NOTES.rdoc +23 -0
- data/lib/beetle/configuration.rb +9 -2
- data/lib/beetle/queue_properties.rb +39 -8
- data/lib/beetle/subscriber.rb +1 -1
- data/lib/beetle/version.rb +1 -1
- data/test/beetle/queue_properties_test.rb +68 -0
- data/test/beetle/subscriber_test.rb +6 -13
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fd1ee5b22d344002924b2b648e036ce98584e270b05af6195115c5bc6aef6438
|
4
|
+
data.tar.gz: f32ef2c465d81cb73ac8453b677419c9117e1f2ab62126feb62dd2227cc1e924
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9521152d635cb12bd96dd87a8153cc20f4d8f9471d9a3d08c2d8d786a53bad2a76b783140ce1e8481b90c2b8dd1f6a391988985380fc4efcc93c30ba01ee013f
|
7
|
+
data.tar.gz: c29b033bcb301006b22bcbeeb4a9e62b6d72a5bcf54093e01aee405ea2c5a8d0f65c3a0e6a69bce0cbe0047cf52780069ae6c9a7d68c53161fea5de0c8b09b27
|
data/README.rdoc
CHANGED
data/RELEASE_NOTES.rdoc
CHANGED
@@ -1,5 +1,28 @@
|
|
1
1
|
= Release Notes
|
2
2
|
|
3
|
+
== Version 3.3.11
|
4
|
+
* Fixed that dead lettering only works correctly with global config option.
|
5
|
+
|
6
|
+
== Version 3.3.10
|
7
|
+
* Support configuring RabbitMQ write timeout.
|
8
|
+
|
9
|
+
== Version 3.3.9
|
10
|
+
* Reduce the number of queue policies created on the servers by allowing
|
11
|
+
the spefication of a default broker policy. You need to install the
|
12
|
+
default policy with a priority of zero to match all queues ever
|
13
|
+
created. This feature is optional.
|
14
|
+
|
15
|
+
== Version 3.3.8
|
16
|
+
* Avoid needless put call when updating queue policies.
|
17
|
+
It seems the additional call to get the current definition of a policy
|
18
|
+
is to be preferred over relying on the idempotency of the PUT call.
|
19
|
+
This helps when adding a new fresh server to a beetle cluster: import
|
20
|
+
the definitions of one of the existing nodes on the fresh node before
|
21
|
+
actually adding it to the list of servers in the client's beetle config..
|
22
|
+
|
23
|
+
== Version 3.3.7
|
24
|
+
* Increased default http api read timeout to handle large server better.
|
25
|
+
|
3
26
|
== Version 3.3.6
|
4
27
|
* Fixed a redis connection leak in gobeetle.
|
5
28
|
|
data/lib/beetle/configuration.rb
CHANGED
@@ -14,6 +14,9 @@ module Beetle
|
|
14
14
|
# Name of the policy update routing key
|
15
15
|
attr_accessor :beetle_policy_updates_routing_key
|
16
16
|
# default logger (defaults to <tt>Logger.new(log_file)</tt>)
|
17
|
+
attr_accessor :broker_default_policy
|
18
|
+
# set this to whatever your brokers have installed as default policy. For example, if you have installed
|
19
|
+
# a policy that makes every queue lazy, it should be set to <tt>{"queue-moode" => "lazy"}</tt>.
|
17
20
|
attr_accessor :logger
|
18
21
|
# defaults to <tt>STDOUT</tt>
|
19
22
|
attr_accessor :redis_logger
|
@@ -104,8 +107,10 @@ module Beetle
|
|
104
107
|
# Whether to update quueue policies synchronously or asynchronously.
|
105
108
|
attr_accessor :update_queue_properties_synchronously
|
106
109
|
|
107
|
-
# Read timeout for http requests to
|
110
|
+
# Read timeout for http requests to RabbitMQ HTTP API
|
108
111
|
attr_accessor :rabbitmq_api_read_timeout
|
112
|
+
# Write timeout for http requests to RabbitMQ HTTP API
|
113
|
+
attr_accessor :rabbitmq_api_write_timeout
|
109
114
|
|
110
115
|
# Returns the port on which the Rabbit API is hosted
|
111
116
|
attr_accessor :api_port
|
@@ -146,6 +151,7 @@ module Beetle
|
|
146
151
|
self.beetle_policy_exchange_name = "beetle-policies"
|
147
152
|
self.beetle_policy_updates_queue_name = "beetle-policy-updates"
|
148
153
|
self.beetle_policy_updates_routing_key = "beetle.policy.update"
|
154
|
+
self.broker_default_policy = {}
|
149
155
|
|
150
156
|
self.gc_threshold = 1.hour.to_i
|
151
157
|
self.redis_server = "localhost:6379"
|
@@ -173,7 +179,8 @@ module Beetle
|
|
173
179
|
|
174
180
|
self.dead_lettering_enabled = false
|
175
181
|
self.dead_lettering_msg_ttl = 1000 # 1 second
|
176
|
-
self.rabbitmq_api_read_timeout =
|
182
|
+
self.rabbitmq_api_read_timeout = 60 # 60 seconds
|
183
|
+
self.rabbitmq_api_write_timeout = 60 # 60 seconds
|
177
184
|
|
178
185
|
self.lazy_queues_enabled = false
|
179
186
|
self.throttling_refresh_interval = 60 # seconds
|
@@ -45,8 +45,11 @@ module Beetle
|
|
45
45
|
return unless options[:dead_lettering] || options[:lazy]
|
46
46
|
|
47
47
|
# no need to worry that the server has the port 5672. Net:HTTP will take care of this. See below.
|
48
|
-
|
49
|
-
|
48
|
+
policy_name = "#{queue_name}_policy"
|
49
|
+
request_url = URI("http://#{server}/api/policies/#{vhost}/#{policy_name}")
|
50
|
+
get_request = Net::HTTP::Get.new(request_url)
|
51
|
+
put_request = Net::HTTP::Put.new(request_url)
|
52
|
+
delete_request = Net::HTTP::Delete.new(request_url)
|
50
53
|
|
51
54
|
# set up queue policy
|
52
55
|
definition = {}
|
@@ -58,19 +61,41 @@ module Beetle
|
|
58
61
|
|
59
62
|
definition["queue-mode"] = "lazy" if options[:lazy]
|
60
63
|
|
61
|
-
|
64
|
+
put_request_body = {
|
62
65
|
"pattern" => "^#{queue_name}$",
|
63
66
|
"priority" => 1,
|
64
67
|
"apply-to" => "queues",
|
65
68
|
"definition" => definition,
|
66
69
|
}
|
67
70
|
|
68
|
-
|
69
|
-
|
71
|
+
is_default_policy = definition == config.broker_default_policy
|
72
|
+
|
73
|
+
get_response = run_rabbit_http_request(request_url, get_request) do |http|
|
74
|
+
http.request(get_request, nil)
|
70
75
|
end
|
71
76
|
|
72
|
-
|
73
|
-
|
77
|
+
case get_response.code
|
78
|
+
when "200"
|
79
|
+
response_body = JSON.parse(get_response.body) rescue {}
|
80
|
+
same_policy = put_request_body.all? { |k,v| response_body[k] == v }
|
81
|
+
if same_policy
|
82
|
+
if is_default_policy
|
83
|
+
run_rabbit_http_request(request_url, delete_request) do |http|
|
84
|
+
http.request(get_request, nil)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
return :ok
|
88
|
+
end
|
89
|
+
when "404"
|
90
|
+
return :ok if is_default_policy
|
91
|
+
end
|
92
|
+
|
93
|
+
put_response = run_rabbit_http_request(request_url, put_request) do |http|
|
94
|
+
http.request(put_request, put_request_body.to_json)
|
95
|
+
end
|
96
|
+
|
97
|
+
unless %w(200 201 204).include?(put_response.code)
|
98
|
+
log_error("Failed to create policy for queue #{queue_name}", put_response)
|
74
99
|
raise FailedRabbitRequest.new("Could not create policy")
|
75
100
|
end
|
76
101
|
|
@@ -131,9 +156,15 @@ module Beetle
|
|
131
156
|
|
132
157
|
def run_rabbit_http_request(uri, request, &block)
|
133
158
|
request.basic_auth(config.user, config.password)
|
134
|
-
request
|
159
|
+
case request.class::METHOD
|
160
|
+
when 'GET'
|
161
|
+
request["Accept"] = "application/json"
|
162
|
+
when 'PUT'
|
163
|
+
request["Content-Type"] = "application/json"
|
164
|
+
end
|
135
165
|
http = Net::HTTP.new(uri.hostname, config.api_port)
|
136
166
|
http.read_timeout = config.rabbitmq_api_read_timeout
|
167
|
+
http.write_timeout = config.rabbitmq_api_write_timeout if http.respond_to?(:write_timeout=)
|
137
168
|
# don't do this in production:
|
138
169
|
# http.set_debug_output(logger.instance_eval{ @logdev.dev })
|
139
170
|
http.start do |instance|
|
data/lib/beetle/subscriber.rb
CHANGED
@@ -180,7 +180,7 @@ module Beetle
|
|
180
180
|
processor = Handler.create(handler, opts)
|
181
181
|
result = m.process(processor)
|
182
182
|
if result.reject?
|
183
|
-
if @client.
|
183
|
+
if @client.queues[queue_name][:dead_lettering]
|
184
184
|
header.reject(:requeue => false)
|
185
185
|
else
|
186
186
|
sleep 1
|
data/lib/beetle/version.rb
CHANGED
@@ -41,6 +41,10 @@ module Beetle
|
|
41
41
|
end
|
42
42
|
|
43
43
|
test "creates a policy by posting to the rabbitmq if dead lettering is enabled" do
|
44
|
+
stub_request(:get, "http://localhost:15672/api/policies/%2F/QUEUE_NAME_policy")
|
45
|
+
.with(basic_auth: ['guest', 'guest'])
|
46
|
+
.to_return(:status => 404)
|
47
|
+
|
44
48
|
stub_request(:put, "http://localhost:15672/api/policies/%2F/QUEUE_NAME_policy")
|
45
49
|
.with(basic_auth: ['guest', 'guest'])
|
46
50
|
.with(:body => {
|
@@ -56,7 +60,59 @@ module Beetle
|
|
56
60
|
@queue_properties.set_queue_policy!(@server, @queue_name, :lazy => false, :dead_lettering => true, :routing_key => "QUEUE_NAME_dead_letter")
|
57
61
|
end
|
58
62
|
|
63
|
+
test "skips the PUT call to rabbitmq if the policy is already defined as desired" do
|
64
|
+
stub_request(:get, "http://localhost:15672/api/policies/%2F/QUEUE_NAME_policy")
|
65
|
+
.with(basic_auth: ['guest', 'guest'])
|
66
|
+
.to_return(:status => 200,
|
67
|
+
:body => {
|
68
|
+
"vhost" => "/",
|
69
|
+
"name" => "QUEUE_NAME_policy",
|
70
|
+
"pattern" => "^QUEUE_NAME$",
|
71
|
+
"priority" => 1,
|
72
|
+
"apply-to" => "queues",
|
73
|
+
"definition" => {
|
74
|
+
"dead-letter-routing-key" => "QUEUE_NAME_dead_letter",
|
75
|
+
"dead-letter-exchange" => ""
|
76
|
+
}}.to_json)
|
77
|
+
|
78
|
+
@queue_properties.set_queue_policy!(@server, @queue_name, :lazy => false, :dead_lettering => true, :routing_key => "QUEUE_NAME_dead_letter")
|
79
|
+
end
|
80
|
+
|
81
|
+
test "deletes policy if its definition corresponds to the broker default policy" do
|
82
|
+
@config.broker_default_policy = { "queue-mode" => "lazy" }
|
83
|
+
stub_request(:get, "http://localhost:15672/api/policies/%2F/QUEUE_NAME_policy")
|
84
|
+
.with(basic_auth: ['guest', 'guest'])
|
85
|
+
.to_return(:status => 200,
|
86
|
+
:body => {
|
87
|
+
"vhost" => "/",
|
88
|
+
"name" => "QUEUE_NAME_policy",
|
89
|
+
"pattern" => "^QUEUE_NAME$",
|
90
|
+
"priority" => 1,
|
91
|
+
"apply-to" => "queues",
|
92
|
+
"definition" => {
|
93
|
+
"queue-mode" => "lazy",
|
94
|
+
}}.to_json)
|
95
|
+
stub_request(:delete, "http://localhost:15672/api/policies/%2F/QUEUE_NAME_policy")
|
96
|
+
.with(basic_auth: ['guest', 'guest'])
|
97
|
+
.to_return(:status => 204)
|
98
|
+
|
99
|
+
@queue_properties.set_queue_policy!(@server, @queue_name, :lazy => true, :dead_lettering => false, :routing_key => "QUEUE_NAME_dead_letter")
|
100
|
+
end
|
101
|
+
|
102
|
+
test "does nothing if its definition corresponds to the broker default policy and the policy does not exist on the server" do
|
103
|
+
@config.broker_default_policy = { "queue-mode" => "lazy" }
|
104
|
+
stub_request(:get, "http://localhost:15672/api/policies/%2F/QUEUE_NAME_policy")
|
105
|
+
.with(basic_auth: ['guest', 'guest'])
|
106
|
+
.to_return(:status => 404)
|
107
|
+
|
108
|
+
@queue_properties.set_queue_policy!(@server, @queue_name, :lazy => true, :dead_lettering => false, :routing_key => "QUEUE_NAME_dead_letter")
|
109
|
+
end
|
110
|
+
|
59
111
|
test "creates a policy by posting to the rabbitmq if lazy queues are enabled" do
|
112
|
+
stub_request(:get, "http://localhost:15672/api/policies/%2F/QUEUE_NAME_policy")
|
113
|
+
.with(basic_auth: ['guest', 'guest'])
|
114
|
+
.to_return(:status => 404)
|
115
|
+
|
60
116
|
stub_request(:put, "http://localhost:15672/api/policies/%2F/QUEUE_NAME_policy")
|
61
117
|
.with(basic_auth: ['guest', 'guest'])
|
62
118
|
.with(:body => {
|
@@ -72,6 +128,10 @@ module Beetle
|
|
72
128
|
end
|
73
129
|
|
74
130
|
test "raises exception when policy couldn't successfully be created" do
|
131
|
+
stub_request(:get, "http://localhost:15672/api/policies/%2F/QUEUE_NAME_policy")
|
132
|
+
.with(basic_auth: ['guest', 'guest'])
|
133
|
+
.to_return(:status => 404)
|
134
|
+
|
75
135
|
stub_request(:put, "http://localhost:15672/api/policies/%2F/QUEUE_NAME_policy")
|
76
136
|
.with(basic_auth: ['guest', 'guest'])
|
77
137
|
.to_return(:status => [405])
|
@@ -82,6 +142,10 @@ module Beetle
|
|
82
142
|
end
|
83
143
|
|
84
144
|
test "can optionally specify a message ttl" do
|
145
|
+
stub_request(:get, "http://localhost:15672/api/policies/%2F/QUEUE_NAME_policy")
|
146
|
+
.with(basic_auth: ['guest', 'guest'])
|
147
|
+
.to_return(:status => 404)
|
148
|
+
|
85
149
|
stub_request(:put, "http://localhost:15672/api/policies/%2F/QUEUE_NAME_policy")
|
86
150
|
.with(basic_auth: ['guest', 'guest'])
|
87
151
|
.with(:body => {
|
@@ -99,6 +163,10 @@ module Beetle
|
|
99
163
|
end
|
100
164
|
|
101
165
|
test "properly encodes the vhost from the configuration" do
|
166
|
+
stub_request(:get, "http://localhost:15672/api/policies/foo%2F/QUEUE_NAME_policy")
|
167
|
+
.with(basic_auth: ['guest', 'guest'])
|
168
|
+
.to_return(:status => 404)
|
169
|
+
|
102
170
|
stub_request(:put, "http://localhost:15672/api/policies/foo%2F/QUEUE_NAME_policy")
|
103
171
|
.with(basic_auth: ['guest', 'guest'])
|
104
172
|
.with(:body => {
|
@@ -224,13 +224,11 @@ module Beetle
|
|
224
224
|
end
|
225
225
|
end
|
226
226
|
|
227
|
-
|
228
227
|
class DeadLetteringCallBackExecutionTest < Minitest::Test
|
229
228
|
def setup
|
230
229
|
@client = Client.new
|
231
|
-
@client.config.dead_lettering_enabled = true
|
232
230
|
@queue = "somequeue"
|
233
|
-
@client.register_queue(@queue)
|
231
|
+
@client.register_queue(@queue, :dead_lettering => true)
|
234
232
|
@sub = @client.send(:subscriber)
|
235
233
|
mq = mock("MQ")
|
236
234
|
mq.expects(:closing?).returns(false)
|
@@ -239,11 +237,7 @@ module Beetle
|
|
239
237
|
@handler = Handler.create(lambda{|*args| raise @exception})
|
240
238
|
# handler method 'processing_completed' should be called under all circumstances
|
241
239
|
@handler.expects(:processing_completed).once
|
242
|
-
@callback = @sub.send(:create_subscription_callback,
|
243
|
-
end
|
244
|
-
|
245
|
-
def teardown
|
246
|
-
@client.config.dead_lettering_enabled = false
|
240
|
+
@callback = @sub.send(:create_subscription_callback, @queue, @queue, @handler, :exceptions => 1)
|
247
241
|
end
|
248
242
|
|
249
243
|
test "should call reject on the message header when processing the handler returns true on reject? if dead lettering has been enabled" do
|
@@ -255,19 +249,18 @@ module Beetle
|
|
255
249
|
header.expects(:reject).with(:requeue => false)
|
256
250
|
@callback.call(header, 'foo')
|
257
251
|
end
|
258
|
-
|
259
252
|
end
|
260
253
|
|
261
254
|
class CallBackExecutionTest < Minitest::Test
|
262
255
|
def setup
|
263
|
-
client = Client.new
|
256
|
+
@client = Client.new
|
264
257
|
@queue = "somequeue"
|
265
|
-
client.register_queue(@queue)
|
266
|
-
@sub = client.send(:subscriber)
|
258
|
+
@client.register_queue(@queue)
|
259
|
+
@sub = @client.send(:subscriber)
|
267
260
|
@exception = Exception.new "murks"
|
268
261
|
@handler = Handler.create(lambda{|*args| raise @exception})
|
269
262
|
@handler.instance_eval { def post_process; raise "shoot"; end }
|
270
|
-
@callback = @sub.send(:create_subscription_callback,
|
263
|
+
@callback = @sub.send(:create_subscription_callback, @queue, @queue, @handler, :exceptions => 1)
|
271
264
|
end
|
272
265
|
|
273
266
|
test "exceptions raised from message processing should be ignored" do
|
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.3.
|
4
|
+
version: 3.3.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stefan Kaes
|
@@ -9,10 +9,10 @@ authors:
|
|
9
9
|
- Ali Jelveh
|
10
10
|
- Sebastian Roebke
|
11
11
|
- Larry Baltz
|
12
|
-
autorequire:
|
12
|
+
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2020-
|
15
|
+
date: 2020-06-18 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: bunny
|
@@ -359,7 +359,7 @@ homepage: https://xing.github.com/beetle/
|
|
359
359
|
licenses: []
|
360
360
|
metadata:
|
361
361
|
changelog_uri: https://github.com/xing/beetle/blob/master/RELEASE_NOTES.rdoc
|
362
|
-
post_install_message:
|
362
|
+
post_install_message:
|
363
363
|
rdoc_options:
|
364
364
|
- "--charset=UTF-8"
|
365
365
|
require_paths:
|
@@ -376,7 +376,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
376
376
|
version: 1.3.7
|
377
377
|
requirements: []
|
378
378
|
rubygems_version: 3.0.8
|
379
|
-
signing_key:
|
379
|
+
signing_key:
|
380
380
|
specification_version: 3
|
381
381
|
summary: High Availability AMQP Messaging with Redundant Queues
|
382
382
|
test_files:
|