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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 19db67e67c4be705a1941803cb05ac03357e32cf
4
- data.tar.gz: 7e85becb93bb0c994b16f533a3cc7b7a34c4d0d6
3
+ metadata.gz: ca9c923df5ace74031777bc88f495b997123dbdb
4
+ data.tar.gz: a0e464a895e6c8f58dc58909ce3afb42e9a0e565
5
5
  SHA512:
6
- metadata.gz: 6ccfebf8a648f1d33e7fc49bc7a03a0b7cac70a93cf3321ec1f1a5cb58018fd671f61ba76eef534aad60143b66eaf7edd1c2f726b3b217d5e2d5be680daca589
7
- data.tar.gz: eca9fba818c940b01ca8969c8ad9794bc31935a22c980f6cedea833507aeeb8bf431b18e1079737cbfbe1f3ddf687b0b28aa0d54ef75095850d707ce52c92431
6
+ metadata.gz: fbc9df84841ec14bc014d255f7ba7ac097ff662ee93e345e9866582393ced2ccd0c5bf054b1358e5d808439d170f81b66e295c37dfe92ce528e3ef23eb908e09
7
+ data.tar.gz: 0fbf1b852344c3e42849725a1ceba069665efaafe6dcc20851e6fe18105e94cff5ff862af9188380c1da34c32adfecb118900b7db69caa9b43613f215095dbf1
data/.travis.yml CHANGED
@@ -3,5 +3,9 @@ rvm:
3
3
  - "2.2"
4
4
  - "2.1"
5
5
  - "2.0"
6
+ - "jruby-9.0.0.0"
6
7
  services:
7
8
  - rabbitmq
9
+ matrix:
10
+ allow_failures:
11
+ - rvm: jruby-9.0.0.0
data/CHANGELOG.md CHANGED
@@ -1,4 +1,36 @@
1
- ## 0.18.0 — (unreleased)
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
- gem.add_runtime_dependency 'bunny', '>= 1.7.0'
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.5'
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,11 @@
1
+ if defined?(JRUBY_VERSION)
2
+ require 'hutch/adapters/march_hare'
3
+ module Hutch
4
+ Adapter = Adapters::MarchHareAdapter
5
+ end
6
+ else
7
+ require 'hutch/adapters/bunny'
8
+ module Hutch
9
+ Adapter = Adapters::BunnyAdapter
10
+ end
11
+ 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 = Bunny.new(connection_params)
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
- ch.prefetch(@config[:channel_prefetch]) if @config[:channel_prefetch]
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
- # Enqueue a failing job that kills the consumer loop
172
- channel_work_pool.shutdown
173
- # Give `timeout` seconds to jobs that are still being processed
174
- channel_work_pool.join(@config[:graceful_exit_timeout])
175
- # If after `timeout` they are still running, they are killed
176
- channel_work_pool.kill
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: Time.now.to_i,
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
- Bunny::Session::DEFAULT_VHOST
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 Bunny::PreconditionFailed => ex
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 Bunny::TCPConnectionFailed => ex
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
@@ -1,4 +1,4 @@
1
1
  module Hutch
2
- VERSION = '0.17.1'.freeze
2
+ VERSION = '0.19.0.pre1'.freeze
3
3
  end
4
4
 
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
- # Take a break from Thread#join every 0.1 seconds to check if we've
25
- # been sent any signals
26
- handle_signals until @broker.wait_on_threads(0.1)
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 |delivery_info, properties, payload|
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
- broker.nack(delivery_info.delivery_tag)
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
@@ -1,3 +1,4 @@
1
+ require 'hutch/adapter'
1
2
  require 'hutch/consumer'
2
3
  require 'hutch/worker'
3
4
  require 'hutch/broker'
@@ -57,4 +58,3 @@ module Hutch
57
58
  broker.publish(*args)
58
59
  end
59
60
  end
60
-
@@ -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 Bunny::Session }
63
+ it { is_expected.to be_a Hutch::Adapters::BunnyAdapter }
64
64
  end
65
65
 
66
- describe '#channel' do
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 '#exchange' do
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
-
@@ -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.17.1
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-08-12 00:00:00.000000000 Z
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: '0'
171
+ version: 1.3.1
168
172
  requirements: []
169
173
  rubyforge_project:
170
174
  rubygems_version: 2.2.2