dkastner-hutch 0.17.1 → 0.19.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +4 -0
- data/CHANGELOG.md +33 -1
- data/README.md +2 -0
- data/hutch.gemspec +8 -2
- data/lib/hutch/acknowledgements/nack_on_all_failures.rb +18 -0
- data/lib/hutch/adapter.rb +11 -0
- data/lib/hutch/adapters/bunny.rb +33 -0
- data/lib/hutch/adapters/march_hare.rb +37 -0
- data/lib/hutch/broker.rb +21 -15
- data/lib/hutch/config.rb +3 -0
- data/lib/hutch/version.rb +1 -1
- data/lib/hutch/worker.rb +47 -5
- data/lib/hutch.rb +1 -1
- data/spec/hutch/broker_spec.rb +62 -10
- data/spec/hutch/worker_spec.rb +54 -0
- data/spec/spec_helper.rb +6 -1
- metadata +8 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ca9c923df5ace74031777bc88f495b997123dbdb
|
4
|
+
data.tar.gz: a0e464a895e6c8f58dc58909ce3afb42e9a0e565
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fbc9df84841ec14bc014d255f7ba7ac097ff662ee93e345e9866582393ced2ccd0c5bf054b1358e5d808439d170f81b66e295c37dfe92ce528e3ef23eb908e09
|
7
|
+
data.tar.gz: 0fbf1b852344c3e42849725a1ceba069665efaafe6dcc20851e6fe18105e94cff5ff862af9188380c1da34c32adfecb118900b7db69caa9b43613f215095dbf1
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,36 @@
|
|
1
|
-
## 0.
|
1
|
+
## 0.19.0 — (unreleased)
|
2
|
+
|
3
|
+
### multi_json Update
|
4
|
+
|
5
|
+
Hutch now depends on multi_json `1.11.x`.
|
6
|
+
|
7
|
+
### Bunny Update
|
8
|
+
|
9
|
+
Bunny is updated to [2.1.0](http://blog.rubyrabbitmq.info/blog/2015/08/16/bunny-2-dot-1-0-is-released/).
|
10
|
+
|
11
|
+
### More Bunny SSL Options
|
12
|
+
|
13
|
+
`:mq_tls_ca_certificates` and `:mq_verify_peer` options will now be passed on to Bunny as `:tls_ca_certificates` and `:verify_peer` respectively.
|
14
|
+
|
15
|
+
Contributed by Kennon Ballou.
|
16
|
+
|
17
|
+
## 0.18.0 — August 16th, 2015
|
18
|
+
|
19
|
+
### JRuby Support (Using March Hare)
|
20
|
+
|
21
|
+
Hutch will now use March Hare when running on JRuby.
|
22
|
+
This will yield significant throughput and core utilisation
|
23
|
+
improvements for workloads with many and/or busy consumers.
|
24
|
+
|
25
|
+
Contributed by Teodor Pripoae.
|
26
|
+
|
27
|
+
|
28
|
+
### Configurable Consumer Thread Pool Size
|
29
|
+
|
30
|
+
`:consumer_pool_size` is a new option (defaults to `1`) which defines
|
31
|
+
Bunny consumer work pool size.
|
32
|
+
|
33
|
+
Contributed by Derek Kastner.
|
2
34
|
|
3
35
|
### Bunny Logger Option
|
4
36
|
|
data/README.md
CHANGED
@@ -289,6 +289,8 @@ Known configuration parameters are:
|
|
289
289
|
* `mq_tls`: should TLS be used? (default: `false`)
|
290
290
|
* `mq_tls_cert`: path to client TLS certificate (public key)
|
291
291
|
* `mq_tls_key`: path to client TLS private key
|
292
|
+
* `mq_tls_ca_certificates`: array of paths to CA keys (if not specified to Hutch, will default to Bunny defaults which are system-dependent)
|
293
|
+
* `mq_verify_peer`: should SSL certificate be verified? (default: `true`)
|
292
294
|
* `require_paths`: array of paths to require
|
293
295
|
* `autoload_rails`: should Hutch command line runner try to automatically load Rails environment files?
|
294
296
|
* `daemonise`: should Hutch runner process daemonise?
|
data/hutch.gemspec
CHANGED
@@ -1,9 +1,15 @@
|
|
1
1
|
require File.expand_path('../lib/hutch/version', __FILE__)
|
2
2
|
|
3
3
|
Gem::Specification.new do |gem|
|
4
|
-
|
4
|
+
if defined?(JRUBY_VERSION)
|
5
|
+
gem.platform = 'java'
|
6
|
+
gem.add_runtime_dependency 'march_hare', '>= 2.11.0'
|
7
|
+
else
|
8
|
+
gem.platform = Gem::Platform::RUBY
|
9
|
+
gem.add_runtime_dependency 'bunny', '>= 2.1.0'
|
10
|
+
end
|
5
11
|
gem.add_runtime_dependency 'carrot-top', '~> 0.0.7'
|
6
|
-
gem.add_runtime_dependency 'multi_json', '~> 1.
|
12
|
+
gem.add_runtime_dependency 'multi_json', '~> 1.11.2'
|
7
13
|
gem.add_runtime_dependency 'activesupport', '>= 3.0'
|
8
14
|
gem.add_development_dependency 'rspec', '~> 3.0'
|
9
15
|
gem.add_development_dependency 'simplecov', '~> 0.7.1'
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'hutch/logging'
|
2
|
+
|
3
|
+
module Hutch
|
4
|
+
module Acknowledgements
|
5
|
+
class NackOnAllFailures
|
6
|
+
include Logging
|
7
|
+
|
8
|
+
def handle(delivery_info, properties, broker, ex)
|
9
|
+
prefix = "message(#{properties.message_id || '-'}): "
|
10
|
+
logger.debug "#{prefix} nacking message"
|
11
|
+
|
12
|
+
broker.nack delivery_info.delivery_tag
|
13
|
+
|
14
|
+
true
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'bunny'
|
2
|
+
require 'forwardable'
|
3
|
+
|
4
|
+
module Hutch
|
5
|
+
module Adapters
|
6
|
+
class BunnyAdapter
|
7
|
+
extend Forwardable
|
8
|
+
|
9
|
+
DEFAULT_VHOST = Bunny::Session::DEFAULT_VHOST
|
10
|
+
|
11
|
+
ConnectionRefused = Bunny::TCPConnectionFailed
|
12
|
+
PreconditionFailed = Bunny::PreconditionFailed
|
13
|
+
|
14
|
+
def_delegators :@connection, :start, :disconnect, :close, :create_channel, :open?
|
15
|
+
|
16
|
+
def initialize(opts={})
|
17
|
+
@connection = Bunny.new(opts)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.decode_message(delivery_info, properties, payload)
|
21
|
+
[delivery_info, properties, payload]
|
22
|
+
end
|
23
|
+
|
24
|
+
def prefetch_channel(ch, prefetch)
|
25
|
+
ch.prefetch(prefetch) if prefetch
|
26
|
+
end
|
27
|
+
|
28
|
+
def current_timestamp
|
29
|
+
Time.now.to_i
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'march_hare'
|
2
|
+
require 'forwardable'
|
3
|
+
|
4
|
+
module Hutch
|
5
|
+
module Adapters
|
6
|
+
class MarchHareAdapter
|
7
|
+
extend Forwardable
|
8
|
+
|
9
|
+
DEFAULT_VHOST = "/"
|
10
|
+
|
11
|
+
ConnectionRefused = MarchHare::ConnectionRefused
|
12
|
+
PreconditionFailed = MarchHare::PreconditionFailed
|
13
|
+
|
14
|
+
def_delegators :@connection, :start, :disconnect, :close, :open?
|
15
|
+
|
16
|
+
def initialize(opts = {})
|
17
|
+
@connection = MarchHare.connect(opts)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.decode_message(delivery_info, payload)
|
21
|
+
[delivery_info, delivery_info.properties, payload]
|
22
|
+
end
|
23
|
+
|
24
|
+
def prefetch_channel(ch, prefetch)
|
25
|
+
ch.prefetch = prefetch if prefetch
|
26
|
+
end
|
27
|
+
|
28
|
+
def create_channel(n = nil, consumer_pool_size = 1)
|
29
|
+
@connection.create_channel(n)
|
30
|
+
end
|
31
|
+
|
32
|
+
def current_timestamp
|
33
|
+
Time.now
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/hutch/broker.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'bunny'
|
2
1
|
require 'carrot-top'
|
3
2
|
require 'securerandom'
|
4
3
|
require 'hutch/logging'
|
@@ -63,7 +62,7 @@ module Hutch
|
|
63
62
|
def open_connection!
|
64
63
|
logger.info "connecting to rabbitmq (#{sanitized_uri})"
|
65
64
|
|
66
|
-
@connection =
|
65
|
+
@connection = Hutch::Adapter.new(connection_params)
|
67
66
|
|
68
67
|
with_bunny_connection_handler(sanitized_uri) do
|
69
68
|
@connection.start
|
@@ -75,8 +74,8 @@ module Hutch
|
|
75
74
|
|
76
75
|
def open_channel!
|
77
76
|
logger.info "opening rabbitmq channel with pool size #{consumer_pool_size}"
|
78
|
-
@channel = connection.create_channel(nil, consumer_pool_size).tap do |ch|
|
79
|
-
|
77
|
+
@channel = @connection.create_channel(nil, consumer_pool_size).tap do |ch|
|
78
|
+
@connection.prefetch_channel(ch, @config[:channel_prefetch])
|
80
79
|
if @config[:publisher_confirms] || @config[:force_publisher_confirms]
|
81
80
|
logger.info 'enabling publisher confirms'
|
82
81
|
ch.confirm_select
|
@@ -168,12 +167,16 @@ module Hutch
|
|
168
167
|
end
|
169
168
|
|
170
169
|
def stop
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
170
|
+
if defined?(JRUBY_VERSION)
|
171
|
+
channel.close
|
172
|
+
else
|
173
|
+
# Enqueue a failing job that kills the consumer loop
|
174
|
+
channel_work_pool.shutdown
|
175
|
+
# Give `timeout` seconds to jobs that are still being processed
|
176
|
+
channel_work_pool.join(@config[:graceful_exit_timeout])
|
177
|
+
# If after `timeout` they are still running, they are killed
|
178
|
+
channel_work_pool.kill
|
179
|
+
end
|
177
180
|
end
|
178
181
|
|
179
182
|
def requeue(delivery_tag)
|
@@ -197,7 +200,7 @@ module Hutch
|
|
197
200
|
|
198
201
|
non_overridable_properties = {
|
199
202
|
routing_key: routing_key,
|
200
|
-
timestamp:
|
203
|
+
timestamp: @connection.current_timestamp,
|
201
204
|
content_type: 'application/json'
|
202
205
|
}
|
203
206
|
properties[:message_id] ||= generate_id
|
@@ -259,13 +262,17 @@ module Hutch
|
|
259
262
|
params[:vhost] = if @config[:mq_vhost] && "" != @config[:mq_vhost]
|
260
263
|
@config[:mq_vhost]
|
261
264
|
else
|
262
|
-
|
265
|
+
Hutch::Adapter::DEFAULT_VHOST
|
263
266
|
end
|
264
267
|
params[:username] = @config[:mq_username]
|
265
268
|
params[:password] = @config[:mq_password]
|
266
269
|
params[:tls] = @config[:mq_tls]
|
267
270
|
params[:tls_key] = @config[:mq_tls_key]
|
268
271
|
params[:tls_cert] = @config[:mq_tls_cert]
|
272
|
+
params[:verify_peer] = @config[:mq_verify_peer]
|
273
|
+
if @config[:mq_tls_ca_certificates]
|
274
|
+
params[:tls_ca_certificates] = @config[:mq_tls_ca_certificates]
|
275
|
+
end
|
269
276
|
params[:heartbeat] = @config[:heartbeat]
|
270
277
|
params[:connection_timeout] = @config[:connection_timeout]
|
271
278
|
params[:read_timeout] = @config[:read_timeout]
|
@@ -318,7 +325,7 @@ module Hutch
|
|
318
325
|
|
319
326
|
def with_bunny_precondition_handler(item)
|
320
327
|
yield
|
321
|
-
rescue
|
328
|
+
rescue Hutch::Adapter::PreconditionFailed => ex
|
322
329
|
logger.error ex.message
|
323
330
|
s = "RabbitMQ responded with 406 Precondition Failed when creating this #{item}. " +
|
324
331
|
"Perhaps it is being redeclared with non-matching attributes"
|
@@ -327,7 +334,7 @@ module Hutch
|
|
327
334
|
|
328
335
|
def with_bunny_connection_handler(uri)
|
329
336
|
yield
|
330
|
-
rescue
|
337
|
+
rescue Hutch::Adapter::ConnectionRefused => ex
|
331
338
|
logger.error "amqp connection error: #{ex.message.downcase}"
|
332
339
|
raise ConnectionError.new("couldn't connect to rabbitmq at #{uri}. Check your configuration, network connectivity and RabbitMQ logs.")
|
333
340
|
end
|
@@ -353,4 +360,3 @@ module Hutch
|
|
353
360
|
end
|
354
361
|
end
|
355
362
|
end
|
356
|
-
|
data/lib/hutch/config.rb
CHANGED
@@ -17,6 +17,8 @@ module Hutch
|
|
17
17
|
mq_tls: false,
|
18
18
|
mq_tls_cert: nil,
|
19
19
|
mq_tls_key: nil,
|
20
|
+
mq_tls_ca_certificates: nil,
|
21
|
+
mq_verify_peer: true,
|
20
22
|
mq_username: 'guest',
|
21
23
|
mq_password: 'guest',
|
22
24
|
mq_api_host: 'localhost',
|
@@ -30,6 +32,7 @@ module Hutch
|
|
30
32
|
require_paths: [],
|
31
33
|
autoload_rails: true,
|
32
34
|
error_handlers: [Hutch::ErrorHandlers::Logger.new],
|
35
|
+
error_acknowledgements: [],
|
33
36
|
tracer: Hutch::Tracers::NullTracer,
|
34
37
|
namespace: nil,
|
35
38
|
daemonise: false,
|
data/lib/hutch/version.rb
CHANGED
data/lib/hutch/worker.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'hutch/message'
|
2
2
|
require 'hutch/logging'
|
3
3
|
require 'hutch/broker'
|
4
|
+
require 'hutch/acknowledgements/nack_on_all_failures'
|
4
5
|
require 'carrot-top'
|
5
6
|
|
6
7
|
module Hutch
|
@@ -21,9 +22,20 @@ module Hutch
|
|
21
22
|
# Set up signal handlers for graceful shutdown
|
22
23
|
register_signal_handlers
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
25
|
+
main_loop
|
26
|
+
end
|
27
|
+
|
28
|
+
def main_loop
|
29
|
+
if defined?(JRUBY_VERSION)
|
30
|
+
# Binds shutdown listener to notify main thread if channel was closed
|
31
|
+
bind_shutdown_handler
|
32
|
+
|
33
|
+
handle_signals until shutdown_not_called?(0.1)
|
34
|
+
else
|
35
|
+
# Take a break from Thread#join every 0.1 seconds to check if we've
|
36
|
+
# been sent any signals
|
37
|
+
handle_signals until @broker.wait_on_threads(0.1)
|
38
|
+
end
|
27
39
|
end
|
28
40
|
|
29
41
|
# Register handlers for SIG{QUIT,TERM,INT} to shut down the worker
|
@@ -53,6 +65,23 @@ module Hutch
|
|
53
65
|
@broker.stop
|
54
66
|
end
|
55
67
|
|
68
|
+
# Binds shutdown handler, called if channel is closed or network Failed
|
69
|
+
def bind_shutdown_handler
|
70
|
+
@broker.channel.on_shutdown do
|
71
|
+
Thread.main[:shutdown_received] = true
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Checks if shutdown handler was called, then sleeps for interval
|
76
|
+
def shutdown_not_called?(interval)
|
77
|
+
if Thread.main[:shutdown_received]
|
78
|
+
true
|
79
|
+
else
|
80
|
+
sleep(interval)
|
81
|
+
false
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
56
85
|
# Set up the queues for each of the worker's consumers.
|
57
86
|
def setup_queues
|
58
87
|
logger.info 'setting up queues'
|
@@ -65,7 +94,8 @@ module Hutch
|
|
65
94
|
queue = @broker.queue(consumer.get_queue_name, consumer.get_arguments)
|
66
95
|
@broker.bind_queue(queue, consumer.routing_keys)
|
67
96
|
|
68
|
-
queue.subscribe(manual_ack: true) do |
|
97
|
+
queue.subscribe(manual_ack: true) do |*args|
|
98
|
+
delivery_info, properties, payload = Hutch::Adapter.decode_message(*args)
|
69
99
|
handle_message(consumer, delivery_info, properties, payload)
|
70
100
|
end
|
71
101
|
end
|
@@ -85,7 +115,7 @@ module Hutch
|
|
85
115
|
with_tracing(consumer_instance).handle(message)
|
86
116
|
broker.ack(delivery_info.delivery_tag)
|
87
117
|
rescue StandardError => ex
|
88
|
-
|
118
|
+
acknowledge_error(delivery_info, properties, broker, ex)
|
89
119
|
handle_error(properties.message_id, payload, consumer, ex)
|
90
120
|
end
|
91
121
|
end
|
@@ -100,11 +130,23 @@ module Hutch
|
|
100
130
|
end
|
101
131
|
end
|
102
132
|
|
133
|
+
def acknowledge_error(delivery_info, properties, broker, ex)
|
134
|
+
acks = error_acknowledgements +
|
135
|
+
[Hutch::Acknowledgements::NackOnAllFailures.new]
|
136
|
+
acks.find do |backend|
|
137
|
+
backend.handle(delivery_info, properties, broker, ex)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
103
141
|
def consumers=(val)
|
104
142
|
if val.empty?
|
105
143
|
logger.warn "no consumer loaded, ensure there's no configuration issue"
|
106
144
|
end
|
107
145
|
@consumers = val
|
108
146
|
end
|
147
|
+
|
148
|
+
def error_acknowledgements
|
149
|
+
Hutch::Config[:error_acknowledgements]
|
150
|
+
end
|
109
151
|
end
|
110
152
|
end
|
data/lib/hutch.rb
CHANGED
data/spec/hutch/broker_spec.rb
CHANGED
@@ -58,20 +58,35 @@ describe Hutch::Broker do
|
|
58
58
|
before { broker.set_up_amqp_connection }
|
59
59
|
after { broker.disconnect }
|
60
60
|
|
61
|
-
describe '#connection' do
|
61
|
+
describe '#connection', adapter: :bunny do
|
62
62
|
subject { super().connection }
|
63
|
-
it { is_expected.to be_a
|
63
|
+
it { is_expected.to be_a Hutch::Adapters::BunnyAdapter }
|
64
64
|
end
|
65
65
|
|
66
|
-
describe '#
|
66
|
+
describe '#connection', adapter: :march_hare do
|
67
|
+
subject { super().connection }
|
68
|
+
it { is_expected.to be_a Hutch::Adapters::MarchHareAdapter }
|
69
|
+
end
|
70
|
+
|
71
|
+
describe '#channel', adapter: :bunny do
|
67
72
|
subject { super().channel }
|
68
73
|
it { is_expected.to be_a Bunny::Channel }
|
69
74
|
end
|
70
75
|
|
71
|
-
describe '#
|
76
|
+
describe '#channel', adapter: :march_hare do
|
77
|
+
subject { super().channel }
|
78
|
+
it { is_expected.to be_a MarchHare::Channel }
|
79
|
+
end
|
80
|
+
|
81
|
+
describe '#exchange', adapter: :bunny do
|
72
82
|
subject { super().exchange }
|
73
83
|
it { is_expected.to be_a Bunny::Exchange }
|
74
84
|
end
|
85
|
+
|
86
|
+
describe '#exchange', adapter: :march_hare do
|
87
|
+
subject { super().exchange }
|
88
|
+
it { is_expected.to be_a MarchHare::Exchange }
|
89
|
+
end
|
75
90
|
end
|
76
91
|
|
77
92
|
context 'when given invalid details' do
|
@@ -86,11 +101,17 @@ describe Hutch::Broker do
|
|
86
101
|
before { config[:channel_prefetch] = prefetch_value }
|
87
102
|
after { broker.disconnect }
|
88
103
|
|
89
|
-
it "set's channel's prefetch" do
|
104
|
+
it "set's channel's prefetch", adapter: :bunny do
|
90
105
|
expect_any_instance_of(Bunny::Channel).
|
91
106
|
to receive(:prefetch).with(prefetch_value)
|
92
107
|
broker.set_up_amqp_connection
|
93
108
|
end
|
109
|
+
|
110
|
+
it "set's channel's prefetch", adapter: :march_hare do
|
111
|
+
expect_any_instance_of(MarchHare::Channel).
|
112
|
+
to receive(:prefetch=).with(prefetch_value)
|
113
|
+
broker.set_up_amqp_connection
|
114
|
+
end
|
94
115
|
end
|
95
116
|
|
96
117
|
context 'with force_publisher_confirms set' do
|
@@ -98,11 +119,17 @@ describe Hutch::Broker do
|
|
98
119
|
before { config[:force_publisher_confirms] = force_publisher_confirms_value }
|
99
120
|
after { broker.disconnect }
|
100
121
|
|
101
|
-
it 'waits for confirmation' do
|
122
|
+
it 'waits for confirmation', adapter: :bunny do
|
102
123
|
expect_any_instance_of(Bunny::Channel).
|
103
124
|
to receive(:confirm_select)
|
104
125
|
broker.set_up_amqp_connection
|
105
126
|
end
|
127
|
+
|
128
|
+
it 'waits for confirmation', adapter: :march_hare do
|
129
|
+
expect_any_instance_of(MarchHare::Channel).
|
130
|
+
to receive(:confirm_select)
|
131
|
+
broker.set_up_amqp_connection
|
132
|
+
end
|
106
133
|
end
|
107
134
|
end
|
108
135
|
|
@@ -213,7 +240,7 @@ describe Hutch::Broker do
|
|
213
240
|
end
|
214
241
|
end
|
215
242
|
|
216
|
-
describe '#stop' do
|
243
|
+
describe '#stop', adapter: :bunny do
|
217
244
|
let(:thread_1) { double('Thread') }
|
218
245
|
let(:thread_2) { double('Thread') }
|
219
246
|
let(:work_pool) { double('Bunny::ConsumerWorkPool') }
|
@@ -232,6 +259,20 @@ describe Hutch::Broker do
|
|
232
259
|
end
|
233
260
|
end
|
234
261
|
|
262
|
+
describe '#stop', adapter: :march_hare do
|
263
|
+
let(:channel) { double('MarchHare::Channel')}
|
264
|
+
|
265
|
+
before do
|
266
|
+
allow(broker).to receive(:channel).and_return(channel)
|
267
|
+
end
|
268
|
+
|
269
|
+
it 'gracefully stops the channel' do
|
270
|
+
expect(channel).to receive(:close)
|
271
|
+
|
272
|
+
broker.stop
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
235
276
|
describe '#publish' do
|
236
277
|
context 'with a valid connection' do
|
237
278
|
before { broker.set_up_amqp_connection }
|
@@ -287,11 +328,17 @@ describe Hutch::Broker do
|
|
287
328
|
end
|
288
329
|
|
289
330
|
context 'with force_publisher_confirms not set in the config' do
|
290
|
-
it 'does not wait for confirms on the channel' do
|
331
|
+
it 'does not wait for confirms on the channel', adapter: :bunny do
|
291
332
|
expect_any_instance_of(Bunny::Channel).
|
292
333
|
to_not receive(:wait_for_confirms)
|
293
334
|
broker.publish('test.key', 'message')
|
294
335
|
end
|
336
|
+
|
337
|
+
it 'does not wait for confirms on the channel', adapter: :march_hare do
|
338
|
+
expect_any_instance_of(MarchHare::Channel).
|
339
|
+
to_not receive(:wait_for_confirms)
|
340
|
+
broker.publish('test.key', 'message')
|
341
|
+
end
|
295
342
|
end
|
296
343
|
|
297
344
|
context 'with force_publisher_confirms set in the config' do
|
@@ -301,11 +348,17 @@ describe Hutch::Broker do
|
|
301
348
|
config[:force_publisher_confirms] = force_publisher_confirms_value
|
302
349
|
end
|
303
350
|
|
304
|
-
it 'waits for confirms on the channel' do
|
351
|
+
it 'waits for confirms on the channel', adapter: :bunny do
|
305
352
|
expect_any_instance_of(Bunny::Channel).
|
306
353
|
to receive(:wait_for_confirms)
|
307
354
|
broker.publish('test.key', 'message')
|
308
355
|
end
|
356
|
+
|
357
|
+
it 'waits for confirms on the channel', adapter: :march_hare do
|
358
|
+
expect_any_instance_of(MarchHare::Channel).
|
359
|
+
to receive(:wait_for_confirms)
|
360
|
+
broker.publish('test.key', 'message')
|
361
|
+
end
|
309
362
|
end
|
310
363
|
end
|
311
364
|
|
@@ -322,4 +375,3 @@ describe Hutch::Broker do
|
|
322
375
|
end
|
323
376
|
end
|
324
377
|
end
|
325
|
-
|
data/spec/hutch/worker_spec.rb
CHANGED
@@ -62,6 +62,25 @@ describe Hutch::Worker do
|
|
62
62
|
worker.handle_message(consumer, delivery_info, properties, payload)
|
63
63
|
end
|
64
64
|
|
65
|
+
context 'when the consumer fails and a requeue is configured' do
|
66
|
+
|
67
|
+
it 'requeues the message' do
|
68
|
+
allow(consumer_instance).to receive(:process).and_raise('failed')
|
69
|
+
requeuer = double
|
70
|
+
allow(requeuer).to receive(:handle).ordered { |delivery_info, properties, broker, e|
|
71
|
+
broker.requeue delivery_info.delivery_tag
|
72
|
+
true
|
73
|
+
}
|
74
|
+
allow(worker).to receive(:error_acknowledgements).and_return([requeuer])
|
75
|
+
expect(broker).to_not receive(:ack)
|
76
|
+
expect(broker).to_not receive(:nack)
|
77
|
+
expect(broker).to receive(:requeue)
|
78
|
+
|
79
|
+
worker.handle_message(consumer, delivery_info, properties, payload)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
|
65
84
|
context 'when the consumer raises an exception' do
|
66
85
|
before { allow(consumer_instance).to receive(:process).and_raise('a consumer error') }
|
67
86
|
|
@@ -94,5 +113,40 @@ describe Hutch::Worker do
|
|
94
113
|
end
|
95
114
|
end
|
96
115
|
end
|
116
|
+
|
117
|
+
|
118
|
+
describe '#acknowledge_error' do
|
119
|
+
let(:delivery_info) { double('Delivery Info', routing_key: '',
|
120
|
+
delivery_tag: 'dt') }
|
121
|
+
let(:properties) { double('Properties', message_id: 'abc123') }
|
122
|
+
|
123
|
+
subject { worker.acknowledge_error delivery_info, properties, broker, StandardError.new }
|
124
|
+
|
125
|
+
it 'stops when it runs a successful acknowledgement' do
|
126
|
+
skip_ack = double handle: false
|
127
|
+
always_ack = double handle: true
|
128
|
+
never_used = double handle: true
|
129
|
+
|
130
|
+
allow(worker).
|
131
|
+
to receive(:error_acknowledgements).
|
132
|
+
and_return([skip_ack, always_ack, never_used])
|
133
|
+
|
134
|
+
expect(never_used).to_not receive(:handle)
|
135
|
+
|
136
|
+
subject
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'defaults to nacking' do
|
140
|
+
skip_ack = double handle: false
|
141
|
+
|
142
|
+
allow(worker).
|
143
|
+
to receive(:error_acknowledgements).
|
144
|
+
and_return([skip_ack, skip_ack])
|
145
|
+
|
146
|
+
expect(broker).to receive(:nack)
|
147
|
+
|
148
|
+
subject
|
149
|
+
end
|
150
|
+
end
|
97
151
|
end
|
98
152
|
|
data/spec/spec_helper.rb
CHANGED
@@ -16,6 +16,12 @@ require 'logger'
|
|
16
16
|
RSpec.configure do |config|
|
17
17
|
config.before(:all) { Hutch::Config.log_level = Logger::FATAL }
|
18
18
|
config.raise_errors_for_deprecations!
|
19
|
+
|
20
|
+
if defined?(JRUBY_VERSION)
|
21
|
+
config.filter_run_excluding adapter: :bunny
|
22
|
+
else
|
23
|
+
config.filter_run_excluding adapter: :march_hare
|
24
|
+
end
|
19
25
|
end
|
20
26
|
|
21
27
|
# Constants (classes, etc) defined within a block passed to this method
|
@@ -32,4 +38,3 @@ end
|
|
32
38
|
def deep_copy(obj)
|
33
39
|
Marshal.load(Marshal.dump(obj))
|
34
40
|
end
|
35
|
-
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dkastner-hutch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.19.0.pre1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Harry Marr
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-09-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bunny
|
@@ -117,6 +117,10 @@ files:
|
|
117
117
|
- examples/producer.rb
|
118
118
|
- hutch.gemspec
|
119
119
|
- lib/hutch.rb
|
120
|
+
- lib/hutch/acknowledgements/nack_on_all_failures.rb
|
121
|
+
- lib/hutch/adapter.rb
|
122
|
+
- lib/hutch/adapters/bunny.rb
|
123
|
+
- lib/hutch/adapters/march_hare.rb
|
120
124
|
- lib/hutch/broker.rb
|
121
125
|
- lib/hutch/cli.rb
|
122
126
|
- lib/hutch/config.rb
|
@@ -162,9 +166,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
162
166
|
version: '0'
|
163
167
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
164
168
|
requirements:
|
165
|
-
- - "
|
169
|
+
- - ">"
|
166
170
|
- !ruby/object:Gem::Version
|
167
|
-
version:
|
171
|
+
version: 1.3.1
|
168
172
|
requirements: []
|
169
173
|
rubyforge_project:
|
170
174
|
rubygems_version: 2.2.2
|