hutch 0.14.0 → 0.15.0
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/.travis.yml +4 -3
- data/CHANGELOG.md +9 -1
- data/README.md +27 -2
- data/lib/hutch/broker.rb +13 -4
- data/lib/hutch/config.rb +7 -2
- data/lib/hutch/consumer.rb +10 -0
- data/lib/hutch/version.rb +1 -1
- data/lib/hutch/worker.rb +1 -1
- data/spec/hutch/broker_spec.rb +23 -2
- data/spec/hutch/config_spec.rb +26 -0
- data/spec/hutch/consumer_spec.rb +27 -1
- data/spec/hutch/worker_spec.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4edfb298acf9e73fb226a3708e76d7e99ad345e3
|
4
|
+
data.tar.gz: d17eb84b63b21b42501570196abe6ef57ca94cde
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 99ba07374f0f8bcf407ef537ea0a8342cb4368cf323c0f41deee27a37e1b6cf156dc6a72645bf2ecc6181219a0723c9c6795035d7ac3cc46ad4783f936edd516
|
7
|
+
data.tar.gz: 8a6abf7f30f6dcb3c88d968deba3115389b6a043293a75609ff5e441c94da55ac3c31d81dad4049f52710ac12bff59d4643f878ee40bac143d35b3070edf8c84
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,12 @@
|
|
1
|
-
## 0.
|
1
|
+
## 0.15.0 — (unreleased)
|
2
|
+
|
3
|
+
Allow to set custom arguments per consumers by using the `arguments` setter.
|
4
|
+
Arguments are usually used by rabbitmq plugins or to set queue policies. You can
|
5
|
+
find a list of supported arguments [here](https://www.rabbitmq.com/extensions.html).
|
6
|
+
|
7
|
+
Contributed by Pierre-Louis Gottfrois.
|
8
|
+
|
9
|
+
## 0.14.0 — Feb 23rd, 2015
|
2
10
|
|
3
11
|
### Configurable Socket Timeouts
|
4
12
|
|
data/README.md
CHANGED
@@ -80,6 +80,19 @@ class FailedPaymentConsumer
|
|
80
80
|
end
|
81
81
|
```
|
82
82
|
|
83
|
+
You can also set custom arguments per consumer. This example declares a consumer with
|
84
|
+
a maximum length of 10 messages:
|
85
|
+
|
86
|
+
```ruby
|
87
|
+
class FailedPaymentConsumer
|
88
|
+
include Hutch::Consumer
|
89
|
+
consume 'gc.ps.payment.failed'
|
90
|
+
arguments 'x-max-length' => 10
|
91
|
+
end
|
92
|
+
```
|
93
|
+
|
94
|
+
Custom queue arguments can be found on [this page](https://www.rabbitmq.com/extensions.html).
|
95
|
+
|
83
96
|
If you are using Hutch with Rails and want to make Hutch log to the Rails
|
84
97
|
logger rather than `stdout`, add this to `config/initializers/hutch.rb`
|
85
98
|
|
@@ -134,8 +147,6 @@ mq_host: broker.yourhost.com
|
|
134
147
|
Passing a setting as a command-line option will overwrite what's specified
|
135
148
|
in the config file, allowing for easy customization.
|
136
149
|
|
137
|
-
|
138
|
-
|
139
150
|
### Loading Consumers
|
140
151
|
|
141
152
|
Using Hutch with a Rails app is simple. Either start Hutch in the working
|
@@ -153,6 +164,20 @@ $ hutch --require path/to/rails-app # loads a rails app
|
|
153
164
|
$ hutch --require path/to/file.rb # loads a ruby file
|
154
165
|
```
|
155
166
|
|
167
|
+
### Stopping Hutch
|
168
|
+
|
169
|
+
Hutch supports graceful stops. That means that if done correctly, Hutch will wait for your consumer to finish processing before exiting.
|
170
|
+
|
171
|
+
To gracefully stop your workers, you may send the following signals to your Hutch processes: `INT`, `TERM`, or `QUIT`.
|
172
|
+
|
173
|
+
```bash
|
174
|
+
kill -SIGINT 123 # or kill -2 123
|
175
|
+
kill -SIGTERM 456 # or kill -15 456
|
176
|
+
kill -SIGQUIT 789 # or kill -3 789
|
177
|
+
```
|
178
|
+
|
179
|
+

|
180
|
+
|
156
181
|
## Producers
|
157
182
|
|
158
183
|
Hutch includes a `publish` method for sending messages to Hutch consumers. When
|
data/lib/hutch/broker.rb
CHANGED
@@ -141,11 +141,11 @@ module Hutch
|
|
141
141
|
end
|
142
142
|
|
143
143
|
# Create / get a durable queue and apply namespace if it exists.
|
144
|
-
def queue(name)
|
144
|
+
def queue(name, arguments = {})
|
145
145
|
with_bunny_precondition_handler('queue') do
|
146
146
|
namespace = @config[:namespace].to_s.downcase.gsub(/[^-_:\.\w]/, "")
|
147
147
|
name = name.prepend(namespace + ":") unless namespace.empty?
|
148
|
-
channel.queue(name, durable: true)
|
148
|
+
channel.queue(name, durable: true, arguments: arguments)
|
149
149
|
end
|
150
150
|
end
|
151
151
|
|
@@ -193,7 +193,12 @@ module Hutch
|
|
193
193
|
end
|
194
194
|
|
195
195
|
def stop
|
196
|
-
|
196
|
+
# Enqueue a failing job that kills the consumer loop
|
197
|
+
channel_work_pool.shutdown
|
198
|
+
# Give `timeout` seconds to jobs that are still being processed
|
199
|
+
channel_work_pool.join(@config[:graceful_exit_timeout])
|
200
|
+
# If after `timeout` they are still running, they are killed
|
201
|
+
channel_work_pool.kill
|
197
202
|
end
|
198
203
|
|
199
204
|
def requeue(delivery_tag)
|
@@ -305,7 +310,11 @@ module Hutch
|
|
305
310
|
end
|
306
311
|
|
307
312
|
def work_pool_threads
|
308
|
-
|
313
|
+
channel_work_pool.threads || []
|
314
|
+
end
|
315
|
+
|
316
|
+
def channel_work_pool
|
317
|
+
@channel.work_pool
|
309
318
|
end
|
310
319
|
|
311
320
|
def generate_id
|
data/lib/hutch/config.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'hutch/error_handlers/logger'
|
2
|
+
require 'erb'
|
2
3
|
require 'logger'
|
3
4
|
|
4
5
|
module Hutch
|
@@ -43,7 +44,11 @@ module Hutch
|
|
43
44
|
connection_timeout: 11,
|
44
45
|
read_timeout: 11,
|
45
46
|
write_timeout: 11,
|
46
|
-
enable_http_api_use: true
|
47
|
+
enable_http_api_use: true,
|
48
|
+
# Number of seconds that a running consumer is given
|
49
|
+
# to finish its job when gracefully exiting Hutch, before
|
50
|
+
# it's killed.
|
51
|
+
graceful_exit_timeout: 11,
|
47
52
|
}.merge(params)
|
48
53
|
end
|
49
54
|
|
@@ -78,7 +83,7 @@ module Hutch
|
|
78
83
|
end
|
79
84
|
|
80
85
|
def self.load_from_file(file)
|
81
|
-
YAML.load(file).each do |attr, value|
|
86
|
+
YAML.load(ERB.new(File.read(file)).result).each do |attr, value|
|
82
87
|
Hutch::Config.send("#{attr}=", value)
|
83
88
|
end
|
84
89
|
end
|
data/lib/hutch/consumer.rb
CHANGED
@@ -32,6 +32,11 @@ module Hutch
|
|
32
32
|
@queue_name = name
|
33
33
|
end
|
34
34
|
|
35
|
+
# Allow to specify custom arguments that will be passed when creating the queue.
|
36
|
+
def arguments(arguments = {})
|
37
|
+
@arguments = arguments
|
38
|
+
end
|
39
|
+
|
35
40
|
# The RabbitMQ queue name for the consumer. This is derived from the
|
36
41
|
# fully-qualified class name. Module separators are replaced with single
|
37
42
|
# colons, camelcased class names are converted to snake case.
|
@@ -42,6 +47,11 @@ module Hutch
|
|
42
47
|
queue_name.downcase
|
43
48
|
end
|
44
49
|
|
50
|
+
# Returns consumer custom arguments.
|
51
|
+
def get_arguments
|
52
|
+
@arguments || {}
|
53
|
+
end
|
54
|
+
|
45
55
|
# Accessor for the consumer's routing key.
|
46
56
|
def routing_keys
|
47
57
|
@routing_keys ||= Set.new
|
data/lib/hutch/version.rb
CHANGED
data/lib/hutch/worker.rb
CHANGED
@@ -62,7 +62,7 @@ module Hutch
|
|
62
62
|
# Bind a consumer's routing keys to its queue, and set up a subscription to
|
63
63
|
# receive messages sent to the queue.
|
64
64
|
def setup_queue(consumer)
|
65
|
-
queue = @broker.queue(consumer.get_queue_name)
|
65
|
+
queue = @broker.queue(consumer.get_queue_name, consumer.get_arguments)
|
66
66
|
@broker.bind_queue(queue, consumer.routing_keys)
|
67
67
|
|
68
68
|
queue.subscribe(manual_ack: true) do |delivery_info, properties, payload|
|
data/spec/hutch/broker_spec.rb
CHANGED
@@ -128,14 +128,16 @@ describe Hutch::Broker do
|
|
128
128
|
|
129
129
|
describe '#queue' do
|
130
130
|
let(:channel) { double('Channel') }
|
131
|
+
let(:arguments) { { foo: :bar } }
|
131
132
|
before { allow(broker).to receive(:channel) { channel } }
|
132
133
|
|
133
134
|
it 'applies a global namespace' do
|
134
135
|
config[:namespace] = 'mirror-all.service'
|
135
136
|
expect(broker.channel).to receive(:queue) do |*args|
|
136
|
-
args.first == '
|
137
|
+
args.first == ''
|
138
|
+
args.last == arguments
|
137
139
|
end
|
138
|
-
broker.queue('test')
|
140
|
+
broker.queue('test', arguments)
|
139
141
|
end
|
140
142
|
end
|
141
143
|
|
@@ -211,6 +213,25 @@ describe Hutch::Broker do
|
|
211
213
|
end
|
212
214
|
end
|
213
215
|
|
216
|
+
describe '#stop' do
|
217
|
+
let(:thread_1) { double('Thread') }
|
218
|
+
let(:thread_2) { double('Thread') }
|
219
|
+
let(:work_pool) { double('Bunny::ConsumerWorkPool') }
|
220
|
+
let(:config) { { graceful_exit_timeout: 2 } }
|
221
|
+
|
222
|
+
before do
|
223
|
+
allow(broker).to receive(:channel_work_pool).and_return(work_pool)
|
224
|
+
end
|
225
|
+
|
226
|
+
it 'gracefully stops the work pool' do
|
227
|
+
expect(work_pool).to receive(:shutdown)
|
228
|
+
expect(work_pool).to receive(:join).with(2)
|
229
|
+
expect(work_pool).to receive(:kill)
|
230
|
+
|
231
|
+
broker.stop
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
214
235
|
describe '#publish' do
|
215
236
|
context 'with a valid connection' do
|
216
237
|
before { broker.set_up_amqp_connection }
|
data/spec/hutch/config_spec.rb
CHANGED
@@ -97,4 +97,30 @@ describe Hutch::Config do
|
|
97
97
|
end
|
98
98
|
end
|
99
99
|
end
|
100
|
+
|
101
|
+
describe '.load_from_file' do
|
102
|
+
let(:host) { 'localhost' }
|
103
|
+
let(:username) { 'calvin' }
|
104
|
+
let(:file) do
|
105
|
+
Tempfile.new('configs.yaml').tap do |t|
|
106
|
+
t.write(config_contents)
|
107
|
+
t.rewind
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context 'when using ERb' do
|
112
|
+
let(:config_contents) do
|
113
|
+
<<-YAML
|
114
|
+
mq_host: 'localhost'
|
115
|
+
mq_username: '<%= "calvin" %>'
|
116
|
+
YAML
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'loads in the config data' do
|
120
|
+
Hutch::Config.load_from_file(file)
|
121
|
+
expect(Hutch::Config.mq_host).to eq host
|
122
|
+
expect(Hutch::Config.mq_username).to eq username
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
100
126
|
end
|
data/spec/hutch/consumer_spec.rb
CHANGED
@@ -22,6 +22,7 @@ describe Hutch::Consumer do
|
|
22
22
|
class ComplexConsumer
|
23
23
|
include Hutch::Consumer
|
24
24
|
consume 'hutch.test1', 'hutch.test2'
|
25
|
+
arguments foo: :bar
|
25
26
|
end
|
26
27
|
end
|
27
28
|
ComplexConsumer
|
@@ -62,11 +63,36 @@ describe Hutch::Consumer do
|
|
62
63
|
end
|
63
64
|
|
64
65
|
describe '.queue_name' do
|
66
|
+
let(:queue_name) { 'foo' }
|
67
|
+
|
65
68
|
it 'overrides the queue name' do
|
66
|
-
|
69
|
+
simple_consumer.queue_name(queue_name)
|
70
|
+
expect(simple_consumer.get_queue_name).to eq(queue_name)
|
67
71
|
end
|
68
72
|
end
|
69
73
|
|
74
|
+
describe '.arguments' do
|
75
|
+
let(:args) { { foo: :bar} }
|
76
|
+
|
77
|
+
it 'overrides the arguments' do
|
78
|
+
simple_consumer.arguments(args)
|
79
|
+
expect(simple_consumer.get_arguments).to eq(args)
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
describe '.get_arguments' do
|
85
|
+
|
86
|
+
context 'when defined' do
|
87
|
+
it { expect(complex_consumer.get_arguments).to eq(foo: :bar) }
|
88
|
+
end
|
89
|
+
|
90
|
+
context 'when not defined' do
|
91
|
+
it { expect(simple_consumer.get_arguments).to eq({}) }
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
70
96
|
describe '.get_queue_name' do
|
71
97
|
|
72
98
|
context 'when queue name has been set explicitly' do
|
data/spec/hutch/worker_spec.rb
CHANGED
@@ -3,7 +3,7 @@ require 'hutch/worker'
|
|
3
3
|
|
4
4
|
describe Hutch::Worker do
|
5
5
|
let(:consumer) { double('Consumer', routing_keys: %w( a b c ),
|
6
|
-
get_queue_name: 'consumer') }
|
6
|
+
get_queue_name: 'consumer', get_arguments: {}) }
|
7
7
|
let(:consumers) { [consumer, double('Consumer')] }
|
8
8
|
let(:broker) { Hutch::Broker.new }
|
9
9
|
subject(:worker) { Hutch::Worker.new(broker, consumers) }
|
@@ -23,7 +23,7 @@ describe Hutch::Worker do
|
|
23
23
|
before { allow(broker).to receive_messages(queue: queue, bind_queue: nil) }
|
24
24
|
|
25
25
|
it 'creates a queue' do
|
26
|
-
expect(broker).to receive(:queue).with(consumer.get_queue_name).and_return(queue)
|
26
|
+
expect(broker).to receive(:queue).with(consumer.get_queue_name, consumer.get_arguments).and_return(queue)
|
27
27
|
worker.setup_queue(consumer)
|
28
28
|
end
|
29
29
|
|
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.15.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: 2015-
|
11
|
+
date: 2015-05-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bunny
|