hutch 0.10.0 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +61 -2
- data/README.md +57 -9
- data/hutch.gemspec +1 -1
- data/lib/hutch.rb +7 -0
- data/lib/hutch/broker.rb +21 -1
- data/lib/hutch/config.rb +11 -1
- data/lib/hutch/version.rb +1 -1
- data/lib/hutch/worker.rb +1 -1
- data/spec/hutch/broker_spec.rb +34 -0
- data/spec/hutch/worker_spec.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b4ae8b34c445db665d717e7c4b935ae246c793c4
|
4
|
+
data.tar.gz: d92e37a658a7a46a08500cf7c14589f7f6df2a17
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 149952fbd91217d9bb7a92c7eac65607b45af0b35aaf0bba3424996376fa0f49fd205efc02b67e5b6a7f7a7a66a1dd22ad0e35ad576772905b0d91dc9da62950
|
7
|
+
data.tar.gz: 6a128089af08c252778bf0cef44cfbbc522aea4938c7a4904c9ea74e21528fc13559a3ecb5011700c36a4e87bdd9b98e171593a3e28829312d3b9162c9774d7e
|
data/CHANGELOG.md
CHANGED
@@ -1,14 +1,73 @@
|
|
1
|
-
## 0.
|
1
|
+
## 0.11.0 — unreleased
|
2
|
+
|
3
|
+
### Publisher Confirms Support
|
4
|
+
|
5
|
+
`:force_publisher_confirms` is a new configuration option that forces `Hutch.publish` to wait
|
6
|
+
for a confirm for every message published. Note that this **will cause a significant drop in throughput**.
|
7
|
+
|
8
|
+
`Hutch::Broker#confirm_select` and `Hutch::Broker#wait_for_confirms` are new public API methods
|
9
|
+
that delegate to their respective `Bunny::Channel` counterparts. `Hutch::Broker#confirm_select`
|
10
|
+
can be used to handle confirms with a callback instead of waiting:
|
11
|
+
|
12
|
+
``` ruby
|
13
|
+
broker.confirm_select do |delivery_tag, multiple, nack|
|
14
|
+
# ...
|
15
|
+
end
|
16
|
+
```
|
17
|
+
|
2
18
|
|
3
19
|
### Bunny Update
|
4
20
|
|
5
|
-
Bunny is updated to
|
21
|
+
Bunny is updated to [1.6.0](http://blog.rubyrabbitmq.info/blog/2014/10/31/bunny-1-dot-6-0-is-released/).
|
22
|
+
|
23
|
+
|
24
|
+
## 0.10.0 — Oct 22, 2014
|
25
|
+
|
26
|
+
### Configuration via URI
|
27
|
+
|
28
|
+
Hutch now supports a new configuration key, `:uri`, which allows
|
29
|
+
connection configuration via a URI.
|
30
|
+
|
31
|
+
Note that since the URI has to include credentials, this option
|
32
|
+
is not available on the command line.
|
33
|
+
|
34
|
+
### Bunny Update
|
35
|
+
|
36
|
+
Bunny is updated to `1.5.1`, which mitigates the POODLE attack
|
37
|
+
by disabling SSL 3.0 where possible.
|
38
|
+
|
39
|
+
### Payload in Error Handlers
|
40
|
+
|
41
|
+
Error handlers will now have access to message payload.
|
42
|
+
|
43
|
+
Contributed by Daniel Farrell.
|
6
44
|
|
7
45
|
### Exceptions in Error Handlers Don't Prevent Nacks
|
8
46
|
|
9
47
|
Exceptions in error handlers no longer prevent messages from being
|
10
48
|
`basic.nack`-ed.
|
11
49
|
|
50
|
+
### Pid File Support
|
51
|
+
|
52
|
+
`:pidfile` is a new configuration option that stores Hutch process
|
53
|
+
PID in a file at provided path.
|
54
|
+
|
55
|
+
Contributed by Rustam Sharshenov.
|
56
|
+
|
57
|
+
### More Info on Message
|
58
|
+
|
59
|
+
Bunny's `delivery_info`, `properties` and payload are now accessible on `Hutch::Message`.
|
60
|
+
|
61
|
+
Contributed by gregory.
|
62
|
+
|
63
|
+
|
64
|
+
### Optional Config Parameters
|
65
|
+
|
66
|
+
`Hutch::Config` constructor now accepts an extra hash of optional
|
67
|
+
configuration parameters.
|
68
|
+
|
69
|
+
Contributed by Ignazio Mostallino.
|
70
|
+
|
12
71
|
|
13
72
|
## 0.9.0 — May 13, 2014
|
14
73
|
|
data/README.md
CHANGED
@@ -26,6 +26,10 @@ over RabbitMQ. Hutch is opinionated: it uses topic exchanges for message
|
|
26
26
|
distribution and makes some assumptions about how consumers and publishers
|
27
27
|
should work.
|
28
28
|
|
29
|
+
With Hutch, consumers are stored in separate files and include the `Hutch::Consumer` module.
|
30
|
+
They are then loaded by a command line runner which connects to RabbitMQ, sets up queues and bindings,
|
31
|
+
and so on. Publishers connect to RabbitMQ via `Hutch.connect` and publish using `Hutch.publish`.
|
32
|
+
|
29
33
|
Hutch uses [Bunny](http://rubybunny.info) under the hood.
|
30
34
|
|
31
35
|
|
@@ -160,6 +164,26 @@ Hutch.connect
|
|
160
164
|
Hutch.publish('routing.key', subject: 'payment', action: 'received')
|
161
165
|
```
|
162
166
|
|
167
|
+
### Producer Configuration
|
168
|
+
|
169
|
+
Producers are not run with the 'hutch' command. You can specify configuration
|
170
|
+
options as follows:
|
171
|
+
|
172
|
+
```ruby
|
173
|
+
Hutch::Config.set(:mq_exchange, 'name')
|
174
|
+
```
|
175
|
+
|
176
|
+
### Publisher Confirms
|
177
|
+
|
178
|
+
For maximum message reliability when producing messages, you can force Hutch to use
|
179
|
+
[Publisher Confirms](https://www.rabbitmq.com/confirms.html) and wait for a confirmation
|
180
|
+
after every message published. This is the safest possible option for publishers
|
181
|
+
but also results in a **significant throughput drop**.
|
182
|
+
|
183
|
+
```ruby
|
184
|
+
Hutch::Config.set(:force_publisher_confirms, true)
|
185
|
+
```
|
186
|
+
|
163
187
|
### Writing Well-Behaved Publishers
|
164
188
|
|
165
189
|
You may need to send messages to Hutch from languages other than Ruby. This
|
@@ -174,11 +198,8 @@ send messages to Hutch.
|
|
174
198
|
- Use message routing keys that match those used in your Hutch consumers.
|
175
199
|
- Be sure your exchanges are marked as durable. In the Ruby AMQP gem, this is
|
176
200
|
done by passing `durable: true` to the exchange creation method.
|
177
|
-
-
|
178
|
-
|
179
|
-
- Wrapping publishing code in transactions or using publisher confirms is
|
180
|
-
highly recommended. This can be slightly tricky, see [this issue][pc-issue]
|
181
|
-
and [this gist][pc-gist] for more info.
|
201
|
+
- Publish messages as persistent.
|
202
|
+
- Using publisher confirms is highly recommended.
|
182
203
|
|
183
204
|
Here's an example of a well-behaved publisher, minus publisher confirms:
|
184
205
|
|
@@ -192,15 +213,42 @@ AMQP.connect(host: config[:host]) do |connection|
|
|
192
213
|
end
|
193
214
|
```
|
194
215
|
|
216
|
+
If using publisher confirms with amqp gem, see [this issue][pc-issue]
|
217
|
+
and [this gist][pc-gist] for more info.
|
218
|
+
|
219
|
+
## Configuration Reference
|
220
|
+
|
221
|
+
### Config File
|
222
|
+
|
223
|
+
It is recommended to use a separate config file, unless you use URIs for connection (see below).
|
224
|
+
|
225
|
+
Known configuration parameters are:
|
226
|
+
|
227
|
+
* `mq_host`: RabbitMQ hostname (default: `localhost`)
|
228
|
+
* `mq_port`: RabbitMQ port (default: `5672`)
|
229
|
+
* `mq_vhost`: vhost to use (default: `/`)
|
230
|
+
* `mq_username`: username to use (default: `guest`, only can connect from localhost as of RabbitMQ 3.3.0)
|
231
|
+
* `mq_password`: password to use (default: `guest`)
|
232
|
+
* `mq_tls`: should TLS be used? (default: `false`)
|
233
|
+
* `mq_tls_cert`: path to client TLS certificate (public key)
|
234
|
+
* `mq_tls_key`: path to client TLS private key
|
235
|
+
* `require_paths`: array of paths to require
|
236
|
+
* `autoload_rails`: should Hutch command line runner try to automatically load Rails environment files?
|
237
|
+
* `daemonise`: should Hutch runner process daemonise?
|
238
|
+
* `pidfile`: path to PID file the runner should use
|
239
|
+
* `channel_prefetch`: basic.qos prefetch value to use (default: `0`, no limit). See Bunny and RabbitMQ documentation.
|
240
|
+
* `publisher_confirms`: enables publisher confirms. Leaves it up to the app how they are
|
241
|
+
tracked (e.g. using `Hutch::Broker#confirm_select` callback or `Hutch::Broker#wait_for_confirms`)
|
242
|
+
* `force_publisher_confirms`: enables publisher confirms, forces `Hutch::Broker#wait_for_confirms` for every publish. **This is the safest option which also offers the lowest throughput**.
|
243
|
+
* `log_level`: log level used by the standard Ruby logger (default: `Logger::INFO`)
|
244
|
+
* `mq_exchange`: exchange to use for publishing (default: `hutch`)
|
245
|
+
|
246
|
+
|
195
247
|
## Supported RabbitMQ Versions
|
196
248
|
|
197
249
|
Hutch requires RabbitMQ 2.x or later. 3.x releases
|
198
250
|
are recommended.
|
199
251
|
|
200
|
-
|
201
|
-
[pc-issue]: https://github.com/ruby-amqp/amqp/issues/92
|
202
|
-
[pc-gist]: https://gist.github.com/3042381
|
203
|
-
|
204
252
|
---
|
205
253
|
|
206
254
|
GoCardless ♥ open source. If you do too, come [join us](https://gocardless.com/jobs/backend_developer).
|
data/hutch.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
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.
|
4
|
+
gem.add_runtime_dependency 'bunny', '>= 1.6.1'
|
5
5
|
gem.add_runtime_dependency 'carrot-top', '~> 0.0.7'
|
6
6
|
gem.add_runtime_dependency 'multi_json', '~> 1.5'
|
7
7
|
gem.add_development_dependency 'rspec', '~> 3.0'
|
data/lib/hutch.rb
CHANGED
data/lib/hutch/broker.rb
CHANGED
@@ -88,6 +88,10 @@ module Hutch
|
|
88
88
|
logger.info 'opening rabbitmq channel'
|
89
89
|
@channel = connection.create_channel.tap do |ch|
|
90
90
|
ch.prefetch(@config[:channel_prefetch]) if @config[:channel_prefetch]
|
91
|
+
if @config[:publisher_confirms] || @config[:force_publisher_confirms]
|
92
|
+
logger.info 'enabling publisher confirms'
|
93
|
+
ch.confirm_select
|
94
|
+
end
|
91
95
|
end
|
92
96
|
end
|
93
97
|
|
@@ -188,10 +192,26 @@ module Hutch
|
|
188
192
|
properties[:message_id] ||= generate_id
|
189
193
|
|
190
194
|
logger.info("publishing message '#{message.inspect}' to #{routing_key}")
|
191
|
-
|
195
|
+
|
196
|
+
response = @exchange.publish(JSON.dump(message), {persistent: true}.
|
192
197
|
merge(properties).
|
193
198
|
merge(global_properties).
|
194
199
|
merge(non_overridable_properties))
|
200
|
+
|
201
|
+
channel.wait_for_confirms if @config[:force_publisher_confirms]
|
202
|
+
response
|
203
|
+
end
|
204
|
+
|
205
|
+
def confirm_select(*args)
|
206
|
+
@channel.confirm_select(*args)
|
207
|
+
end
|
208
|
+
|
209
|
+
def wait_for_confirms
|
210
|
+
@channel.wait_for_confirms
|
211
|
+
end
|
212
|
+
|
213
|
+
def using_publisher_confirmations?
|
214
|
+
@channel.using_publisher_confirmations?
|
195
215
|
end
|
196
216
|
|
197
217
|
private
|
data/lib/hutch/config.rb
CHANGED
@@ -31,7 +31,13 @@ module Hutch
|
|
31
31
|
namespace: nil,
|
32
32
|
daemonise: false,
|
33
33
|
pidfile: nil,
|
34
|
-
channel_prefetch: 0
|
34
|
+
channel_prefetch: 0,
|
35
|
+
# enables publisher confirms, leaves it up to the app
|
36
|
+
# how they are tracked
|
37
|
+
publisher_confirms: false,
|
38
|
+
# like `publisher_confirms` above but also
|
39
|
+
# forces waiting for a confirm for every publish
|
40
|
+
force_publisher_confirms: false
|
35
41
|
}.merge(params)
|
36
42
|
end
|
37
43
|
|
@@ -61,6 +67,10 @@ module Hutch
|
|
61
67
|
@config
|
62
68
|
end
|
63
69
|
|
70
|
+
def self.to_hash
|
71
|
+
self.user_config
|
72
|
+
end
|
73
|
+
|
64
74
|
def self.load_from_file(file)
|
65
75
|
YAML.load(file).each do |attr, value|
|
66
76
|
Hutch::Config.send("#{attr}=", value)
|
data/lib/hutch/version.rb
CHANGED
data/lib/hutch/worker.rb
CHANGED
@@ -65,7 +65,7 @@ module Hutch
|
|
65
65
|
queue = @broker.queue(consumer.get_queue_name)
|
66
66
|
@broker.bind_queue(queue, consumer.routing_keys)
|
67
67
|
|
68
|
-
queue.subscribe(
|
68
|
+
queue.subscribe(manual_ack: true) do |delivery_info, properties, payload|
|
69
69
|
handle_message(consumer, delivery_info, properties, payload)
|
70
70
|
end
|
71
71
|
end
|
data/spec/hutch/broker_spec.rb
CHANGED
@@ -92,6 +92,18 @@ describe Hutch::Broker do
|
|
92
92
|
broker.set_up_amqp_connection
|
93
93
|
end
|
94
94
|
end
|
95
|
+
|
96
|
+
context 'with force_publisher_confirms set' do
|
97
|
+
let(:force_publisher_confirms_value) { true }
|
98
|
+
before { config[:force_publisher_confirms] = force_publisher_confirms_value }
|
99
|
+
after { broker.disconnect }
|
100
|
+
|
101
|
+
it 'waits for confirmation' do
|
102
|
+
expect_any_instance_of(Bunny::Channel).
|
103
|
+
to receive(:confirm_select)
|
104
|
+
broker.set_up_amqp_connection
|
105
|
+
end
|
106
|
+
end
|
95
107
|
end
|
96
108
|
|
97
109
|
describe '#set_up_api_connection', rabbitmq: true do
|
@@ -252,6 +264,28 @@ describe Hutch::Broker do
|
|
252
264
|
end
|
253
265
|
end
|
254
266
|
end
|
267
|
+
|
268
|
+
context 'with force_publisher_confirms not set in the config' do
|
269
|
+
it 'does not wait for confirms on the channel' do
|
270
|
+
expect_any_instance_of(Bunny::Channel).
|
271
|
+
to_not receive(:wait_for_confirms)
|
272
|
+
broker.publish('test.key', 'message')
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
context 'with force_publisher_confirms set in the config' do
|
277
|
+
let(:force_publisher_confirms_value) { true }
|
278
|
+
|
279
|
+
before do
|
280
|
+
config[:force_publisher_confirms] = force_publisher_confirms_value
|
281
|
+
end
|
282
|
+
|
283
|
+
it 'waits for confirms on the channel' do
|
284
|
+
expect_any_instance_of(Bunny::Channel).
|
285
|
+
to receive(:wait_for_confirms)
|
286
|
+
broker.publish('test.key', 'message')
|
287
|
+
end
|
288
|
+
end
|
255
289
|
end
|
256
290
|
|
257
291
|
context 'without a valid connection' do
|
data/spec/hutch/worker_spec.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hutch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Harry Marr
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-11-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bunny
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '>='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.
|
19
|
+
version: 1.6.1
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '>='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 1.
|
26
|
+
version: 1.6.1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: carrot-top
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|