hutch 0.21.0-java → 0.25.0-java
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 +5 -5
- data/.gitignore +3 -0
- data/.rspec +1 -0
- data/.travis.yml +11 -12
- data/.yardopts +5 -0
- data/CHANGELOG.md +118 -1
- data/Gemfile +15 -4
- data/Guardfile +13 -4
- data/README.md +274 -24
- data/Rakefile +8 -1
- data/hutch.gemspec +6 -7
- data/lib/hutch.rb +11 -8
- data/lib/hutch/adapters/march_hare.rb +1 -1
- data/lib/hutch/broker.rb +113 -110
- data/lib/hutch/cli.rb +42 -11
- data/lib/hutch/config.rb +209 -59
- data/lib/hutch/error_handlers.rb +1 -0
- data/lib/hutch/error_handlers/airbrake.rb +44 -16
- data/lib/hutch/error_handlers/base.rb +15 -0
- data/lib/hutch/error_handlers/honeybadger.rb +33 -18
- data/lib/hutch/error_handlers/logger.rb +12 -6
- data/lib/hutch/error_handlers/opbeat.rb +30 -0
- data/lib/hutch/error_handlers/sentry.rb +14 -6
- data/lib/hutch/logging.rb +5 -5
- data/lib/hutch/publisher.rb +75 -0
- data/lib/hutch/tracers.rb +1 -0
- data/lib/hutch/tracers/opbeat.rb +37 -0
- data/lib/hutch/version.rb +1 -1
- data/lib/hutch/waiter.rb +104 -0
- data/lib/hutch/worker.rb +50 -66
- data/lib/yard-settings/handler.rb +38 -0
- data/lib/yard-settings/yard-settings.rb +2 -0
- data/spec/hutch/broker_spec.rb +162 -77
- data/spec/hutch/cli_spec.rb +16 -3
- data/spec/hutch/config_spec.rb +83 -22
- data/spec/hutch/error_handlers/airbrake_spec.rb +25 -10
- data/spec/hutch/error_handlers/honeybadger_spec.rb +24 -2
- data/spec/hutch/error_handlers/logger_spec.rb +14 -1
- data/spec/hutch/error_handlers/opbeat_spec.rb +37 -0
- data/spec/hutch/error_handlers/sentry_spec.rb +18 -1
- data/spec/hutch/logger_spec.rb +12 -6
- data/spec/hutch/waiter_spec.rb +51 -0
- data/spec/hutch/worker_spec.rb +33 -4
- data/spec/spec_helper.rb +7 -5
- data/spec/tracers/opbeat_spec.rb +44 -0
- data/templates/default/class/html/settings.erb +0 -0
- data/templates/default/class/setup.rb +4 -0
- data/templates/default/fulldoc/html/css/hutch.css +13 -0
- data/templates/default/layout/html/setup.rb +7 -0
- data/templates/default/method_details/html/settings.erb +5 -0
- data/templates/default/method_details/setup.rb +4 -0
- data/templates/default/method_details/text/settings.erb +0 -0
- data/templates/default/module/html/settings.erb +40 -0
- data/templates/default/module/setup.rb +4 -0
- metadata +41 -38
data/lib/hutch/worker.rb
CHANGED
@@ -2,17 +2,18 @@ require 'hutch/message'
|
|
2
2
|
require 'hutch/logging'
|
3
3
|
require 'hutch/broker'
|
4
4
|
require 'hutch/acknowledgements/nack_on_all_failures'
|
5
|
+
require 'hutch/waiter'
|
5
6
|
require 'carrot-top'
|
7
|
+
require 'securerandom'
|
6
8
|
|
7
9
|
module Hutch
|
8
10
|
class Worker
|
9
11
|
include Logging
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
-
def initialize(broker, consumers)
|
13
|
+
def initialize(broker, consumers, setup_procs)
|
14
14
|
@broker = broker
|
15
15
|
self.consumers = consumers
|
16
|
+
self.setup_procs = setup_procs
|
16
17
|
end
|
17
18
|
|
18
19
|
# Run the main event loop. The consumers will be set up with queues, and
|
@@ -20,46 +21,11 @@ module Hutch
|
|
20
21
|
# never returns.
|
21
22
|
def run
|
22
23
|
setup_queues
|
24
|
+
setup_procs.each(&:call)
|
23
25
|
|
24
|
-
|
25
|
-
register_signal_handlers
|
26
|
-
|
27
|
-
main_loop
|
28
|
-
end
|
29
|
-
|
30
|
-
def main_loop
|
31
|
-
if defined?(JRUBY_VERSION)
|
32
|
-
# Binds shutdown listener to notify main thread if channel was closed
|
33
|
-
bind_shutdown_handler
|
34
|
-
|
35
|
-
handle_signals until shutdown_not_called?(0.1)
|
36
|
-
else
|
37
|
-
# Take a break from Thread#join every 0.1 seconds to check if we've
|
38
|
-
# been sent any signals
|
39
|
-
handle_signals until @broker.wait_on_threads(0.1)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
# Register handlers for SIG{QUIT,TERM,INT} to shut down the worker
|
44
|
-
# gracefully. Forceful shutdowns are very bad!
|
45
|
-
def register_signal_handlers
|
46
|
-
Thread.main[:signal_queue] = []
|
47
|
-
supported_shutdown_signals.each do |sig|
|
48
|
-
# This needs to be reentrant, so we queue up signals to be handled
|
49
|
-
# in the run loop, rather than acting on signals here
|
50
|
-
trap(sig) do
|
51
|
-
Thread.main[:signal_queue] << sig
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
26
|
+
Waiter.wait_until_signaled
|
55
27
|
|
56
|
-
|
57
|
-
def handle_signals
|
58
|
-
signal = Thread.main[:signal_queue].shift
|
59
|
-
if signal
|
60
|
-
logger.info "caught sig#{signal.downcase}, stopping hutch..."
|
61
|
-
stop
|
62
|
-
end
|
28
|
+
stop
|
63
29
|
end
|
64
30
|
|
65
31
|
# Stop a running worker by killing all subscriber threads.
|
@@ -67,36 +33,24 @@ module Hutch
|
|
67
33
|
@broker.stop
|
68
34
|
end
|
69
35
|
|
70
|
-
# Binds shutdown handler, called if channel is closed or network Failed
|
71
|
-
def bind_shutdown_handler
|
72
|
-
@broker.channel.on_shutdown do
|
73
|
-
Thread.main[:shutdown_received] = true
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
# Checks if shutdown handler was called, then sleeps for interval
|
78
|
-
def shutdown_not_called?(interval)
|
79
|
-
if Thread.main[:shutdown_received]
|
80
|
-
true
|
81
|
-
else
|
82
|
-
sleep(interval)
|
83
|
-
false
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
36
|
# Set up the queues for each of the worker's consumers.
|
88
37
|
def setup_queues
|
89
38
|
logger.info 'setting up queues'
|
90
|
-
@consumers.
|
39
|
+
vetted = @consumers.reject { |c| group_configured? && group_restricted?(c) }
|
40
|
+
vetted.each do |c|
|
41
|
+
setup_queue(c)
|
42
|
+
end
|
91
43
|
end
|
92
44
|
|
93
45
|
# Bind a consumer's routing keys to its queue, and set up a subscription to
|
94
46
|
# receive messages sent to the queue.
|
95
47
|
def setup_queue(consumer)
|
48
|
+
logger.info "setting up queue: #{consumer.get_queue_name}"
|
49
|
+
|
96
50
|
queue = @broker.queue(consumer.get_queue_name, consumer.get_arguments)
|
97
51
|
@broker.bind_queue(queue, consumer.routing_keys)
|
98
52
|
|
99
|
-
queue.subscribe(manual_ack: true) do |*args|
|
53
|
+
queue.subscribe(consumer_tag: unique_consumer_tag, manual_ack: true) do |*args|
|
100
54
|
delivery_info, properties, payload = Hutch::Adapter.decode_message(*args)
|
101
55
|
handle_message(consumer, delivery_info, properties, payload)
|
102
56
|
end
|
@@ -106,7 +60,7 @@ module Hutch
|
|
106
60
|
# for wrapping up the message and passing it to the consumer.
|
107
61
|
def handle_message(consumer, delivery_info, properties, payload)
|
108
62
|
serializer = consumer.get_serializer || Hutch::Config[:serializer]
|
109
|
-
logger.
|
63
|
+
logger.debug {
|
110
64
|
spec = serializer.binary? ? "#{payload.bytesize} bytes" : "#{payload}"
|
111
65
|
"message(#{properties.message_id || '-'}): " +
|
112
66
|
"routing key: #{delivery_info.routing_key}, " +
|
@@ -120,16 +74,16 @@ module Hutch
|
|
120
74
|
@broker.ack(delivery_info.delivery_tag)
|
121
75
|
rescue => ex
|
122
76
|
acknowledge_error(delivery_info, properties, @broker, ex)
|
123
|
-
handle_error(properties
|
77
|
+
handle_error(properties, payload, consumer, ex)
|
124
78
|
end
|
125
79
|
|
126
80
|
def with_tracing(klass)
|
127
81
|
Hutch::Config[:tracer].new(klass)
|
128
82
|
end
|
129
83
|
|
130
|
-
def handle_error(
|
84
|
+
def handle_error(*args)
|
131
85
|
Hutch::Config[:error_handlers].each do |backend|
|
132
|
-
backend.handle(
|
86
|
+
backend.handle(*args)
|
133
87
|
end
|
134
88
|
end
|
135
89
|
|
@@ -154,8 +108,38 @@ module Hutch
|
|
154
108
|
|
155
109
|
private
|
156
110
|
|
157
|
-
def
|
158
|
-
|
111
|
+
def group_configured?
|
112
|
+
if group.present? && consumer_groups.blank?
|
113
|
+
logger.info 'Consumer groups are blank'
|
114
|
+
end
|
115
|
+
group.present?
|
116
|
+
end
|
117
|
+
|
118
|
+
def group_restricted?(consumer)
|
119
|
+
consumers_to_load = consumer_groups[group]
|
120
|
+
if consumers_to_load
|
121
|
+
!allowed_consumers.include?(consumer.name)
|
122
|
+
else
|
123
|
+
true
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def group
|
128
|
+
Hutch::Config[:group]
|
129
|
+
end
|
130
|
+
|
131
|
+
def consumer_groups
|
132
|
+
Hutch::Config[:consumer_groups]
|
133
|
+
end
|
134
|
+
|
135
|
+
attr_accessor :setup_procs
|
136
|
+
|
137
|
+
def unique_consumer_tag
|
138
|
+
prefix = Hutch::Config[:consumer_tag_prefix]
|
139
|
+
unique_part = SecureRandom.uuid
|
140
|
+
"#{prefix}-#{unique_part}".tap do |tag|
|
141
|
+
raise "Tag must be 255 bytes long at most, current one is #{tag.bytesize} ('#{tag}')" if tag.bytesize > 255
|
142
|
+
end
|
159
143
|
end
|
160
144
|
end
|
161
145
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# :nodoc:
|
2
|
+
class SettingsHandlerBase < YARD::Handlers::Ruby::Base
|
3
|
+
handles method_call :string_setting
|
4
|
+
handles method_call :number_setting
|
5
|
+
handles method_call :boolean_setting
|
6
|
+
|
7
|
+
namespace_only
|
8
|
+
|
9
|
+
def process
|
10
|
+
name = statement.parameters.first.jump(:tstring_content, :ident).source
|
11
|
+
object = YARD::CodeObjects::MethodObject.new(namespace, name)
|
12
|
+
register(object)
|
13
|
+
|
14
|
+
# Modify the code object for the new instance method
|
15
|
+
object.dynamic = true
|
16
|
+
# Add custom metadata to the object
|
17
|
+
object['custom_field'] = '(Found using method_missing)'
|
18
|
+
|
19
|
+
# Module-level configuration notes
|
20
|
+
hutch_config = YARD::CodeObjects::ModuleObject.new(:root, "Hutch::Config")
|
21
|
+
collection_name = statement.first.first
|
22
|
+
default_value = statement.parameters[1].jump(:tstring_content, :ident).source
|
23
|
+
|
24
|
+
(hutch_config['setting_rows'] ||= []) << {
|
25
|
+
name: name,
|
26
|
+
default_value: default_value,
|
27
|
+
type: collection_name.sub('_setting', '').capitalize,
|
28
|
+
description: object.docstring,
|
29
|
+
first_line_of_description: first_line_of_description(object)
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
def first_line_of_description(object)
|
34
|
+
return '' if object.docstring.blank?
|
35
|
+
|
36
|
+
object.docstring.lines.first
|
37
|
+
end
|
38
|
+
end
|
data/spec/hutch/broker_spec.rb
CHANGED
@@ -2,8 +2,16 @@ require 'spec_helper'
|
|
2
2
|
require 'hutch/broker'
|
3
3
|
|
4
4
|
describe Hutch::Broker do
|
5
|
-
|
6
|
-
|
5
|
+
before do
|
6
|
+
Hutch::Config.initialize(client_logger: Hutch::Logging.logger)
|
7
|
+
@config = Hutch::Config.to_hash
|
8
|
+
end
|
9
|
+
let!(:config) { @config }
|
10
|
+
after do
|
11
|
+
Hutch::Config.instance_variable_set(:@config, nil)
|
12
|
+
Hutch::Config.initialize
|
13
|
+
end
|
14
|
+
let(:broker) { Hutch::Broker.new(config) }
|
7
15
|
|
8
16
|
describe '#connect' do
|
9
17
|
before { allow(broker).to receive(:set_up_amqp_connection) }
|
@@ -53,93 +61,183 @@ describe Hutch::Broker do
|
|
53
61
|
end
|
54
62
|
end
|
55
63
|
|
56
|
-
describe '#set_up_amqp_connection'
|
57
|
-
|
58
|
-
|
59
|
-
|
64
|
+
describe '#set_up_amqp_connection' do
|
65
|
+
it 'opens a connection, channel and declares an exchange' do
|
66
|
+
expect(broker).to receive(:open_connection!).ordered
|
67
|
+
expect(broker).to receive(:open_channel!).ordered
|
68
|
+
expect(broker).to receive(:declare_exchange!).ordered
|
60
69
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
end
|
70
|
+
broker.set_up_amqp_connection
|
71
|
+
end
|
72
|
+
end
|
65
73
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
74
|
+
describe '#open_connection', rabbitmq: true do
|
75
|
+
describe 'return value' do
|
76
|
+
subject { broker.open_connection }
|
77
|
+
after { subject.close }
|
70
78
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
end
|
79
|
+
it(nil, adapter: :bunny) { is_expected.to be_a Hutch::Adapters::BunnyAdapter }
|
80
|
+
it(nil, adapter: :march_hare) { is_expected.to be_a Hutch::Adapters::MarchHareAdapter }
|
81
|
+
end
|
75
82
|
|
76
|
-
|
77
|
-
|
78
|
-
|
83
|
+
context 'when given invalid details' do
|
84
|
+
before { config[:mq_host] = 'notarealhost' }
|
85
|
+
it { expect { broker.open_connection }.to raise_error(StandardError) }
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'does not set #connection' do
|
89
|
+
connection = broker.open_connection
|
90
|
+
|
91
|
+
expect(broker.connection).to be_nil
|
92
|
+
|
93
|
+
connection.close
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'when configured with a URI' do
|
97
|
+
context 'which specifies the port' do
|
98
|
+
before { config[:uri] = 'amqp://guest:guest@127.0.0.1:5672/' }
|
99
|
+
|
100
|
+
it 'successfully connects' do
|
101
|
+
c = broker.open_connection
|
102
|
+
expect(c).to be_open
|
103
|
+
c.close
|
104
|
+
end
|
79
105
|
end
|
80
106
|
|
81
|
-
|
82
|
-
|
83
|
-
|
107
|
+
context 'which does not specify port and uses the amqp scheme' do
|
108
|
+
before { config[:uri] = 'amqp://guest:guest@127.0.0.1/' }
|
109
|
+
|
110
|
+
it 'successfully connects' do
|
111
|
+
c = broker.open_connection
|
112
|
+
expect(c).to be_open
|
113
|
+
c.close
|
114
|
+
end
|
84
115
|
end
|
85
116
|
|
86
|
-
|
87
|
-
|
88
|
-
|
117
|
+
context 'which specifies the amqps scheme' do
|
118
|
+
before { config[:uri] = 'amqps://guest:guest@127.0.0.1/' }
|
119
|
+
|
120
|
+
it 'utilises TLS' do
|
121
|
+
expect(Hutch::Adapter).to receive(:new).with(
|
122
|
+
hash_including(tls: true, port: 5671)
|
123
|
+
).and_return(instance_double('Hutch::Adapter', start: nil))
|
124
|
+
|
125
|
+
broker.open_connection
|
126
|
+
end
|
89
127
|
end
|
90
128
|
end
|
129
|
+
end
|
91
130
|
|
92
|
-
|
93
|
-
|
94
|
-
|
131
|
+
describe '#open_connection!' do
|
132
|
+
it 'sets the #connection to #open_connection' do
|
133
|
+
connection = double('connection').as_null_object
|
134
|
+
|
135
|
+
expect(broker).to receive(:open_connection).and_return(connection)
|
136
|
+
|
137
|
+
broker.open_connection!
|
95
138
|
|
96
|
-
|
139
|
+
expect(broker.connection).to eq(connection)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
describe '#open_channel', rabbitmq: true do
|
144
|
+
before { broker.open_connection! }
|
145
|
+
after { broker.disconnect }
|
146
|
+
|
147
|
+
describe 'return value' do
|
148
|
+
subject { broker.open_channel }
|
149
|
+
|
150
|
+
it(nil, adapter: :bunny) { is_expected.to be_a Bunny::Channel }
|
151
|
+
it(nil, adapter: :march_hare) { is_expected.to be_a MarchHare::Channel }
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'does not set #channel' do
|
155
|
+
broker.open_channel
|
156
|
+
expect(broker.channel).to be_nil
|
97
157
|
end
|
98
158
|
|
99
159
|
context 'with channel_prefetch set' do
|
100
160
|
let(:prefetch_value) { 1 }
|
101
161
|
before { config[:channel_prefetch] = prefetch_value }
|
102
|
-
after { broker.disconnect }
|
103
162
|
|
104
163
|
it "set's channel's prefetch", adapter: :bunny do
|
105
|
-
expect_any_instance_of(Bunny::Channel).
|
106
|
-
|
107
|
-
broker.set_up_amqp_connection
|
164
|
+
expect_any_instance_of(Bunny::Channel).to receive(:prefetch).with(prefetch_value)
|
165
|
+
broker.open_channel
|
108
166
|
end
|
109
167
|
|
110
168
|
it "set's channel's prefetch", adapter: :march_hare do
|
111
|
-
expect_any_instance_of(MarchHare::Channel).
|
112
|
-
|
113
|
-
broker.set_up_amqp_connection
|
169
|
+
expect_any_instance_of(MarchHare::Channel).to receive(:prefetch=).with(prefetch_value)
|
170
|
+
broker.open_channel
|
114
171
|
end
|
115
172
|
end
|
116
173
|
|
117
174
|
context 'with force_publisher_confirms set' do
|
118
175
|
let(:force_publisher_confirms_value) { true }
|
119
176
|
before { config[:force_publisher_confirms] = force_publisher_confirms_value }
|
120
|
-
after { broker.disconnect }
|
121
177
|
|
122
178
|
it 'waits for confirmation', adapter: :bunny do
|
123
|
-
expect_any_instance_of(Bunny::Channel).
|
124
|
-
|
125
|
-
broker.set_up_amqp_connection
|
179
|
+
expect_any_instance_of(Bunny::Channel).to receive(:confirm_select)
|
180
|
+
broker.open_channel
|
126
181
|
end
|
127
182
|
|
128
183
|
it 'waits for confirmation', adapter: :march_hare do
|
129
|
-
expect_any_instance_of(MarchHare::Channel).
|
130
|
-
|
131
|
-
broker.set_up_amqp_connection
|
184
|
+
expect_any_instance_of(MarchHare::Channel).to receive(:confirm_select)
|
185
|
+
broker.open_channel
|
132
186
|
end
|
133
187
|
end
|
134
188
|
end
|
135
189
|
|
190
|
+
describe '#open_channel!' do
|
191
|
+
it 'sets the #channel to #open_channel' do
|
192
|
+
channel = double('channel').as_null_object
|
193
|
+
|
194
|
+
expect(broker).to receive(:open_channel).and_return(channel)
|
195
|
+
|
196
|
+
broker.open_channel!
|
197
|
+
|
198
|
+
expect(broker.channel).to eq(channel)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
describe '#declare_exchange' do
|
203
|
+
before do
|
204
|
+
broker.open_connection!
|
205
|
+
broker.open_channel!
|
206
|
+
end
|
207
|
+
after { broker.disconnect }
|
208
|
+
|
209
|
+
describe 'return value' do
|
210
|
+
subject { broker.declare_exchange }
|
211
|
+
|
212
|
+
it(nil, adapter: :bunny) { is_expected.to be_a Bunny::Exchange }
|
213
|
+
it(nil, adapter: :march_hare) { is_expected.to be_a MarchHare::Exchange }
|
214
|
+
end
|
215
|
+
|
216
|
+
it 'does not set #exchange' do
|
217
|
+
broker.declare_exchange
|
218
|
+
expect(broker.exchange).to be_nil
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
describe '#declare_exchange!' do
|
223
|
+
it 'sets the #exchange to #declare_exchange' do
|
224
|
+
exchange = double('exchange').as_null_object
|
225
|
+
|
226
|
+
expect(broker).to receive(:declare_exchange).and_return(exchange)
|
227
|
+
|
228
|
+
broker.declare_exchange!
|
229
|
+
|
230
|
+
expect(broker.exchange).to eq(exchange)
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
136
234
|
describe '#set_up_api_connection', rabbitmq: true do
|
137
235
|
context 'with valid details' do
|
138
236
|
before { broker.set_up_api_connection }
|
139
237
|
after { broker.disconnect }
|
140
238
|
|
141
239
|
describe '#api_client' do
|
142
|
-
subject {
|
240
|
+
subject { broker.api_client }
|
143
241
|
it { is_expected.to be_a CarrotTop }
|
144
242
|
end
|
145
243
|
end
|
@@ -149,7 +247,7 @@ describe Hutch::Broker do
|
|
149
247
|
after { broker.disconnect }
|
150
248
|
let(:set_up_api_connection) { ->{ broker.set_up_api_connection } }
|
151
249
|
|
152
|
-
specify { expect(set_up_api_connection).to raise_error }
|
250
|
+
specify { expect(set_up_api_connection).to raise_error(StandardError) }
|
153
251
|
end
|
154
252
|
end
|
155
253
|
|
@@ -192,7 +290,7 @@ describe Hutch::Broker do
|
|
192
290
|
|
193
291
|
describe '#bind_queue' do
|
194
292
|
|
195
|
-
around { |example| broker.connect { example.run } }
|
293
|
+
around { |example| broker.connect(host: "127.0.0.1") { example.run } }
|
196
294
|
|
197
295
|
let(:routing_keys) { %w( a b c ) }
|
198
296
|
let(:queue) { double('Queue', bind: nil, unbind: nil, name: 'consumer') }
|
@@ -225,21 +323,6 @@ describe Hutch::Broker do
|
|
225
323
|
end
|
226
324
|
end
|
227
325
|
|
228
|
-
describe '#wait_on_threads' do
|
229
|
-
let(:thread) { double('Thread') }
|
230
|
-
before { allow(broker).to receive(:work_pool_threads).and_return(threads) }
|
231
|
-
|
232
|
-
context 'when all threads finish within the timeout' do
|
233
|
-
let(:threads) { [double(join: thread), double(join: thread)] }
|
234
|
-
specify { expect(broker.wait_on_threads(1)).to be_truthy }
|
235
|
-
end
|
236
|
-
|
237
|
-
context 'when timeout expires for one thread' do
|
238
|
-
let(:threads) { [double(join: thread), double(join: nil)] }
|
239
|
-
specify { expect(broker.wait_on_threads(1)).to be_falsey }
|
240
|
-
end
|
241
|
-
end
|
242
|
-
|
243
326
|
describe '#stop', adapter: :bunny do
|
244
327
|
let(:thread_1) { double('Thread') }
|
245
328
|
let(:thread_2) { double('Thread') }
|
@@ -280,12 +363,12 @@ describe Hutch::Broker do
|
|
280
363
|
|
281
364
|
it 'publishes to the exchange' do
|
282
365
|
expect(broker.exchange).to receive(:publish).once
|
283
|
-
broker.publish('test.key',
|
366
|
+
broker.publish('test.key', {key: "value"})
|
284
367
|
end
|
285
368
|
|
286
369
|
it 'sets default properties' do
|
287
370
|
expect(broker.exchange).to receive(:publish).with(
|
288
|
-
JSON.dump("
|
371
|
+
JSON.dump({key: "value"}),
|
289
372
|
hash_including(
|
290
373
|
persistent: true,
|
291
374
|
routing_key: 'test.key',
|
@@ -293,12 +376,12 @@ describe Hutch::Broker do
|
|
293
376
|
)
|
294
377
|
)
|
295
378
|
|
296
|
-
broker.publish('test.key',
|
379
|
+
broker.publish('test.key', {key: "value"})
|
297
380
|
end
|
298
381
|
|
299
382
|
it 'allows passing message properties' do
|
300
383
|
expect(broker.exchange).to receive(:publish).once
|
301
|
-
broker.publish('test.key',
|
384
|
+
broker.publish('test.key', {key: "value"}, {expiration: "2000", persistent: false})
|
302
385
|
end
|
303
386
|
|
304
387
|
context 'when there are global properties' do
|
@@ -309,8 +392,8 @@ describe Hutch::Broker do
|
|
309
392
|
|
310
393
|
it 'merges the properties' do
|
311
394
|
expect(broker.exchange).
|
312
|
-
to receive(:publish).with('"
|
313
|
-
broker.publish('test.key',
|
395
|
+
to receive(:publish).with('{"key":"value"}', hash_including(app_id: 'app'))
|
396
|
+
broker.publish('test.key', {key: "value"})
|
314
397
|
end
|
315
398
|
end
|
316
399
|
|
@@ -321,8 +404,8 @@ describe Hutch::Broker do
|
|
321
404
|
|
322
405
|
it 'calls the proc and merges the properties' do
|
323
406
|
expect(broker.exchange).
|
324
|
-
to receive(:publish).with('"
|
325
|
-
broker.publish('test.key',
|
407
|
+
to receive(:publish).with('{"key":"value"}', hash_including(app_id: 'app'))
|
408
|
+
broker.publish('test.key', {key: "value"})
|
326
409
|
end
|
327
410
|
end
|
328
411
|
end
|
@@ -331,13 +414,13 @@ describe Hutch::Broker do
|
|
331
414
|
it 'does not wait for confirms on the channel', adapter: :bunny do
|
332
415
|
expect_any_instance_of(Bunny::Channel).
|
333
416
|
to_not receive(:wait_for_confirms)
|
334
|
-
broker.publish('test.key',
|
417
|
+
broker.publish('test.key', {key: "value"})
|
335
418
|
end
|
336
419
|
|
337
420
|
it 'does not wait for confirms on the channel', adapter: :march_hare do
|
338
421
|
expect_any_instance_of(MarchHare::Channel).
|
339
422
|
to_not receive(:wait_for_confirms)
|
340
|
-
broker.publish('test.key',
|
423
|
+
broker.publish('test.key', {key: "value"})
|
341
424
|
end
|
342
425
|
end
|
343
426
|
|
@@ -351,26 +434,28 @@ describe Hutch::Broker do
|
|
351
434
|
it 'waits for confirms on the channel', adapter: :bunny do
|
352
435
|
expect_any_instance_of(Bunny::Channel).
|
353
436
|
to receive(:wait_for_confirms)
|
354
|
-
broker.publish('test.key',
|
437
|
+
broker.publish('test.key', {key: "value"})
|
355
438
|
end
|
356
439
|
|
357
440
|
it 'waits for confirms on the channel', adapter: :march_hare do
|
358
441
|
expect_any_instance_of(MarchHare::Channel).
|
359
442
|
to receive(:wait_for_confirms)
|
360
|
-
broker.publish('test.key',
|
443
|
+
broker.publish('test.key', {key: "value"})
|
361
444
|
end
|
362
445
|
end
|
363
446
|
end
|
364
447
|
|
365
448
|
context 'without a valid connection' do
|
449
|
+
before { broker.set_up_amqp_connection; broker.disconnect }
|
450
|
+
|
366
451
|
it 'raises an exception' do
|
367
|
-
expect { broker.publish('test.key',
|
452
|
+
expect { broker.publish('test.key', {key: "value"}) }.
|
368
453
|
to raise_exception(Hutch::PublishError)
|
369
454
|
end
|
370
455
|
|
371
456
|
it 'logs an error' do
|
372
457
|
expect(broker.logger).to receive(:error)
|
373
|
-
broker.publish('test.key',
|
458
|
+
broker.publish('test.key', {key: "value"}) rescue nil
|
374
459
|
end
|
375
460
|
end
|
376
461
|
end
|