hutch 0.28.0 → 1.1.1
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/.github/workflows/test.yml +42 -0
- data/CHANGELOG.md +116 -1
- data/Gemfile +3 -0
- data/LICENSE +1 -0
- data/README.md +58 -7
- data/bin/ci/before_build_docker.sh +20 -0
- data/bin/ci/install_on_debian.sh +36 -7
- data/hutch.gemspec +7 -9
- data/lib/hutch/adapters/bunny.rb +4 -0
- data/lib/hutch/adapters/march_hare.rb +4 -0
- data/lib/hutch/broker.rb +4 -3
- data/lib/hutch/cli.rb +3 -0
- data/lib/hutch/config.rb +20 -9
- data/lib/hutch/consumer.rb +29 -8
- data/lib/hutch/error_handlers/bugsnag.rb +30 -0
- data/lib/hutch/error_handlers/sentry.rb +6 -11
- data/lib/hutch/error_handlers/sentry_raven.rb +31 -0
- data/lib/hutch/error_handlers.rb +2 -0
- data/lib/hutch/serializers/json.rb +1 -1
- data/lib/hutch/tracers/datadog.rb +17 -0
- data/lib/hutch/tracers.rb +1 -0
- data/lib/hutch/version.rb +1 -1
- data/lib/hutch/worker.rb +1 -1
- data/spec/hutch/broker_spec.rb +1 -1
- data/spec/hutch/config_spec.rb +38 -0
- data/spec/hutch/consumer_spec.rb +36 -24
- data/spec/hutch/error_handlers/bugsnag_spec.rb +55 -0
- data/spec/hutch/error_handlers/sentry_raven_spec.rb +37 -0
- data/spec/hutch/error_handlers/sentry_spec.rb +4 -2
- data/spec/hutch/tracers/datadog_spec.rb +44 -0
- data/spec/hutch/worker_spec.rb +2 -2
- metadata +29 -19
- data/.travis.yml +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9725ddb3e39e305bad95abd6c8605c1d9828691904bb2ae31430fd22d88bd180
|
4
|
+
data.tar.gz: db1d87d81de0f89c84b1ec387c66443aa9ead6be2d71b50b6cee32e9146dd080
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 296138c5cb4c08340f4a72bb8d30009402272f9843efffd0dc1d647328ca1531d188fd3b5a9a15f891f4a8447dbf5f72a7a583aa702f1c999fc557c1ab4ac024
|
7
|
+
data.tar.gz: 2c0406261d2535d5e5d00037e20e29f5cb781e337732491cf36195231e5d647b75c0d96d74c0861afa36cfb24575a0e2b34ce06f59693a98b84342cf1d52ad95
|
@@ -0,0 +1,42 @@
|
|
1
|
+
name: Test
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ master ]
|
6
|
+
pull_request:
|
7
|
+
branches: [ master ]
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
test:
|
11
|
+
|
12
|
+
runs-on: ubuntu-latest
|
13
|
+
|
14
|
+
services:
|
15
|
+
rabbitmq:
|
16
|
+
image: rabbitmq:3-management
|
17
|
+
ports:
|
18
|
+
- 5672:5672
|
19
|
+
- 15672:15672
|
20
|
+
options: --name rabbitmq
|
21
|
+
|
22
|
+
strategy:
|
23
|
+
fail-fast: false
|
24
|
+
matrix:
|
25
|
+
ruby-version: ['jruby-9.2.19.0', 'jruby-9.3.0.0', 'jruby-head']
|
26
|
+
|
27
|
+
steps:
|
28
|
+
- uses: actions/checkout@v2
|
29
|
+
- name: Set up Ruby
|
30
|
+
# To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
|
31
|
+
# change this to (see https://github.com/ruby/setup-ruby#versioning):
|
32
|
+
uses: ruby/setup-ruby@v1
|
33
|
+
# uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
|
34
|
+
with:
|
35
|
+
ruby-version: ${{ matrix.ruby-version }}
|
36
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
37
|
+
- name: Set up RabbitMQ
|
38
|
+
run: |
|
39
|
+
until sudo lsof -i:5672; do echo "Waiting for RabbitMQ to start..."; sleep 1; done
|
40
|
+
./bin/ci/before_build_docker.sh
|
41
|
+
- name: Run tests
|
42
|
+
run: bundle exec rspec spec
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,119 @@
|
|
1
|
-
##
|
1
|
+
## 1.1.1 (March 18th, 2022)
|
2
|
+
### Dependency Bump
|
3
|
+
|
4
|
+
Hutch now allows ActiveSupport 7.x.
|
5
|
+
|
6
|
+
|
7
|
+
## 1.1.0 (July 26th, 2021)
|
8
|
+
|
9
|
+
### Bugsnag Error Handler
|
10
|
+
|
11
|
+
Contributed by @ivanhuang1.
|
12
|
+
|
13
|
+
GitHub issue: [#362](https://github.com/ruby-amqp/hutch/pull/362)
|
14
|
+
|
15
|
+
### Datadog Tracer
|
16
|
+
|
17
|
+
Contributed by Karol @Azdaroth Galanciak.
|
18
|
+
|
19
|
+
GitHub issue: [#360](https://github.com/ruby-amqp/hutch/pull/360)
|
20
|
+
|
21
|
+
### Updated Sentry Error Handler
|
22
|
+
|
23
|
+
Contributed by Karol @Azdaroth Galanciak.
|
24
|
+
|
25
|
+
GitHub issue: [#363](https://github.com/ruby-amqp/hutch/pull/363)
|
26
|
+
|
27
|
+
### Type Casting for Values Set Using Hutch::Config.set
|
28
|
+
|
29
|
+
Values set with `Hutch::Config.set` now have expected setting type casting
|
30
|
+
applied to them.
|
31
|
+
|
32
|
+
Contributed by Karol @Azdaroth Galanciak.
|
33
|
+
|
34
|
+
GitHub issue: [#358](https://github.com/ruby-amqp/hutch/pull/358)
|
35
|
+
|
36
|
+
### Wider MultiJson Adoption
|
37
|
+
|
38
|
+
Contributed by Ulysse @BuonOmo Buonomo.
|
39
|
+
|
40
|
+
GitHub issue: [#356](https://github.com/ruby-amqp/hutch/pull/356)
|
41
|
+
|
42
|
+
### README Corrections
|
43
|
+
|
44
|
+
Contributed by Johan @johankok Kok.
|
45
|
+
|
46
|
+
GitHub issue: [#353](https://github.com/ruby-amqp/hutch/pull/353)
|
47
|
+
|
48
|
+
## 1.0.0 (April 8th, 2020)
|
49
|
+
|
50
|
+
Hutch has been around for several years. It is time to ship a 1.0. With it we try to correct
|
51
|
+
a few of overly opinionated decisions from recent releases. This means this release
|
52
|
+
contains potentially breaking changes.
|
53
|
+
|
54
|
+
### Breaking Changes
|
55
|
+
|
56
|
+
* Hutch will no longer configure any queue type (such as [quorum queues](https://www.rabbitmq.com/quorum-queues.html))
|
57
|
+
or queue mode (used by classic [lazy queues](https://www.rabbitmq.com/lazy-queues.html))
|
58
|
+
by default as that can be breaking change for existing Hutch and RabbitMQ installations due to the
|
59
|
+
[property equivalence requirement](https://www.rabbitmq.com/queues.html#property-equivalence) in AMQP 0-9-1.
|
60
|
+
|
61
|
+
This means **some defaults introduced in `0.28.0` ([gocardless/hutch#341](https://github.com/gocardless/hutch/pull/341)) were reverted**.
|
62
|
+
The user has to opt in to configure the queue type and mode and other [optional arguments](https://www.rabbitmq.com/queues.html#optional-arguments) they need to use.
|
63
|
+
Most optional arguments can be set via [policies](https://www.rabbitmq.com/parameters.html#policies) which is always the recommended approach.
|
64
|
+
Queue type, unfortunately, is not one of them as different queue types have completely different
|
65
|
+
implementation details, on disk data formats and so on.
|
66
|
+
|
67
|
+
To use a quorum queue, use the `quorum_queue` consumer DSL method:
|
68
|
+
|
69
|
+
``` ruby
|
70
|
+
class ConsumerUsingQuorumQueue
|
71
|
+
include Hutch::Consumer
|
72
|
+
consume 'hutch.test1'
|
73
|
+
# when in doubt, prefer using a policy to this DSL
|
74
|
+
# https://www.rabbitmq.com/parameters.html#policies
|
75
|
+
arguments 'x-key': :value
|
76
|
+
|
77
|
+
quorum_queue
|
78
|
+
end
|
79
|
+
```
|
80
|
+
|
81
|
+
To use a classic lazy queue, use the `lazy_queue` consumer DSL method:
|
82
|
+
|
83
|
+
``` ruby
|
84
|
+
class ConsumerUsingLazyQueue
|
85
|
+
include Hutch::Consumer
|
86
|
+
consume 'hutch.test1'
|
87
|
+
# when in doubt, prefer using a policy to this DSL
|
88
|
+
# https://www.rabbitmq.com/parameters.html#policies
|
89
|
+
arguments 'x-key': :value
|
90
|
+
|
91
|
+
lazy_queue
|
92
|
+
classic_queue
|
93
|
+
end
|
94
|
+
```
|
95
|
+
|
96
|
+
By default Hutch will not configure any `x-queue-type` or `x-queue-mode` optional arguments
|
97
|
+
which is identical to RabbitMQ defaults (a regular classic queue).
|
98
|
+
|
99
|
+
Note that as of RabbitMQ 3.8.2, an omitted `x-queue-type` is [considered to be identical](https://github.com/rabbitmq/rabbitmq-common/issues/341)
|
100
|
+
to `x-queue-type` set to `classic` by RabbitMQ server.
|
101
|
+
|
102
|
+
|
103
|
+
#### Enhancements
|
104
|
+
|
105
|
+
* Exchange type is now configurable via the `mq_exchange_type` config setting. Supported exchanges must be
|
106
|
+
compatible with topic exchanges (e.g. wrap it). Default value is `topic`.
|
107
|
+
|
108
|
+
This feature is limited to topic and delayed message exchange plugins and is mostly
|
109
|
+
useful for forward compatibility.
|
110
|
+
|
111
|
+
Contributed by Michael Bumann.
|
112
|
+
|
113
|
+
GitHub issue: [gocardless/hutch#349](https://github.com/gocardless/hutch/pull/349)
|
114
|
+
|
115
|
+
|
116
|
+
## 0.28.0 (March 17, 2020)
|
2
117
|
|
3
118
|
### Enhancements
|
4
119
|
|
data/Gemfile
CHANGED
@@ -20,11 +20,14 @@ group :development, :test do
|
|
20
20
|
gem "simplecov", "~> 0.12"
|
21
21
|
|
22
22
|
gem "sentry-raven"
|
23
|
+
gem "sentry-ruby"
|
23
24
|
gem "honeybadger"
|
24
25
|
gem "coveralls", "~> 0.8.15", require: false
|
25
26
|
gem "newrelic_rpm"
|
27
|
+
gem "ddtrace"
|
26
28
|
gem "airbrake", "~> 10.0"
|
27
29
|
gem "rollbar"
|
30
|
+
gem "bugsnag"
|
28
31
|
end
|
29
32
|
|
30
33
|
group :development, :darwin do
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|

|
2
2
|
|
3
3
|
[](http://badge.fury.io/rb/hutch)
|
4
|
-
[](https://travis-ci.org/gocardless/hutch)
|
5
4
|
[](https://codeclimate.com/github/gocardless/hutch)
|
6
5
|
|
7
6
|
Hutch is a Ruby library for enabling asynchronous inter-service communication
|
@@ -39,7 +38,7 @@ gem install hutch
|
|
39
38
|
|
40
39
|
## Requirements
|
41
40
|
|
42
|
-
- Hutch requires Ruby 2.
|
41
|
+
- Hutch requires Ruby 2.4+ or JRuby 9K.
|
43
42
|
- Hutch requires RabbitMQ 3.3 or later.
|
44
43
|
|
45
44
|
## Overview
|
@@ -59,8 +58,8 @@ Hutch uses [Bunny](http://rubybunny.info) or [March Hare](http://rubymarchhare.i
|
|
59
58
|
### Project Maturity
|
60
59
|
|
61
60
|
Hutch is a mature project that was originally extracted from production systems
|
62
|
-
at [GoCardless](https://gocardless.com) in 2013 and is now maintained by
|
63
|
-
|
61
|
+
at [GoCardless](https://gocardless.com) in 2013 and is now maintained by its contributors
|
62
|
+
and users.
|
64
63
|
|
65
64
|
## Consumers
|
66
65
|
|
@@ -188,6 +187,12 @@ This will enable NewRelic custom instrumentation:
|
|
188
187
|
Hutch::Config.set(:tracer, Hutch::Tracers::NewRelic)
|
189
188
|
```
|
190
189
|
|
190
|
+
And this will enable Datadog custom instrumentation:
|
191
|
+
|
192
|
+
```ruby
|
193
|
+
Hutch::Config.set(:tracer, Hutch::Tracers::Datadog)
|
194
|
+
```
|
195
|
+
|
191
196
|
Batteries included!
|
192
197
|
|
193
198
|
## Running Hutch
|
@@ -246,7 +251,7 @@ and the consumers are not loaded in development environment you will need to
|
|
246
251
|
trigger the autoloading in an initializer with
|
247
252
|
|
248
253
|
```ruby
|
249
|
-
::Zeitwerk::Loader.eager_load_all
|
254
|
+
::Zeitwerk::Loader.eager_load_all
|
250
255
|
```
|
251
256
|
|
252
257
|
or with something more specific like
|
@@ -259,13 +264,37 @@ Dir.glob(File.join('app/consumers', '*_consumer.rb')).each do |consumer|
|
|
259
264
|
end
|
260
265
|
```
|
261
266
|
|
267
|
+
### Consumer Groups
|
268
|
+
|
269
|
+
It is possible to load only a subset of consumers. This is done by defining a consumer
|
270
|
+
group under the `consumer_groups` configuration key:
|
271
|
+
|
272
|
+
``` yaml
|
273
|
+
consumer_groups:
|
274
|
+
payments:
|
275
|
+
- DepositConsumer
|
276
|
+
- CashoutConsumer
|
277
|
+
notification:
|
278
|
+
- EmailNotificationConsumer
|
279
|
+
```
|
280
|
+
|
281
|
+
To only load a group of consumers, use the `--only-group` option:
|
282
|
+
|
283
|
+
``` shell
|
284
|
+
hutch --only-group=payments --config=/path/to/hutch.yaml
|
285
|
+
```
|
286
|
+
|
287
|
+
### Loading Consumers Manually (One-by-One)
|
288
|
+
|
262
289
|
To require files that define consumers manually, simply pass each file as an
|
263
290
|
option to `--require`. Hutch will automatically detect whether you've provided
|
264
291
|
a Rails app or a standard file, and take the appropriate behaviour:
|
265
292
|
|
266
293
|
```bash
|
267
|
-
|
268
|
-
|
294
|
+
# loads a rails app
|
295
|
+
hutch --require path/to/rails-app
|
296
|
+
# loads a ruby file
|
297
|
+
hutch --require path/to/file.rb
|
269
298
|
```
|
270
299
|
|
271
300
|
### Stopping Hutch
|
@@ -384,6 +413,7 @@ Known configuration parameters are:
|
|
384
413
|
* `automatically_recover`: Bunny's enable/disable network recovery (default: `true`)
|
385
414
|
* `network_recovery_interval`: Bunny's reconnect interval (default: `1`)
|
386
415
|
* `tracer`: tracer to use to track message processing
|
416
|
+
* `namespace`: A namespace string to help group your queues (default: `nil`)
|
387
417
|
|
388
418
|
### Environment variables
|
389
419
|
|
@@ -442,6 +472,13 @@ Generate with
|
|
442
472
|
<td><tt>HUTCH_MQ_EXCHANGE</tt></td>
|
443
473
|
<td><p>RabbitMQ Exchange to use for publishing</p></td>
|
444
474
|
</tr>
|
475
|
+
<tr>
|
476
|
+
<td><tt>mq_exchange_type</tt></td>
|
477
|
+
<td>topic</td>
|
478
|
+
<td>String</td>
|
479
|
+
<td><tt>HUTCH_MQ_EXCHANGE_TYPE</tt></td>
|
480
|
+
<td><p>RabbitMQ Exchange type to use for publishing</p></td>
|
481
|
+
</tr>
|
445
482
|
<tr>
|
446
483
|
<td><tt>mq_vhost</tt></td>
|
447
484
|
<td>/</td>
|
@@ -624,5 +661,19 @@ Generate with
|
|
624
661
|
<td><tt>HUTCH_CONSUMER_TAG_PREFIX</tt></td>
|
625
662
|
<td><p>Prefix displayed on the consumers tags.</p></td>
|
626
663
|
</tr>
|
664
|
+
<tr>
|
665
|
+
<td><tt>namespace</tt></td>
|
666
|
+
<td>nil</td>
|
667
|
+
<td>String</td>
|
668
|
+
<td><tt>HUTCH_NAMESPACE</tt></td>
|
669
|
+
<td><p>A namespace to help group your queues</p></td>
|
670
|
+
</tr>
|
671
|
+
<tr>
|
672
|
+
<td><tt>group</tt></td>
|
673
|
+
<td>''</td>
|
674
|
+
<td>String</td>
|
675
|
+
<td><tt>HUTCH_GROUP</tt></td>
|
676
|
+
<td></td>
|
677
|
+
</tr>
|
627
678
|
</tbody>
|
628
679
|
</table>
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
CTL=${MARCH_HARE_RABBITMQCTL:="docker exec rabbitmq rabbitmqctl"}
|
4
|
+
PLUGINS=${MARCH_HARE_RABBITMQ_PLUGINS:="docker exec rabbitmq rabbitmq-plugins"}
|
5
|
+
|
6
|
+
$PLUGINS enable rabbitmq_management
|
7
|
+
|
8
|
+
sleep 3
|
9
|
+
|
10
|
+
# guest:guest has full access to /
|
11
|
+
|
12
|
+
$CTL add_vhost /
|
13
|
+
# $CTL add_user guest guest # already exists
|
14
|
+
$CTL set_permissions -p / guest ".*" ".*" ".*"
|
15
|
+
|
16
|
+
# Reduce retention policy for faster publishing of stats
|
17
|
+
$CTL eval 'supervisor2:terminate_child(rabbit_mgmt_sup_sup, rabbit_mgmt_sup), application:set_env(rabbitmq_management, sample_retention_policies, [{global, [{605, 1}]}, {basic, [{605, 1}]}, {detailed, [{10, 1}]}]), rabbit_mgmt_sup_sup:start_child().'
|
18
|
+
$CTL eval 'supervisor2:terminate_child(rabbit_mgmt_agent_sup_sup, rabbit_mgmt_agent_sup), application:set_env(rabbitmq_management_agent, sample_retention_policies, [{global, [{605, 1}]}, {basic, [{605, 1}]}, {detailed, [{10, 1}]}]), rabbit_mgmt_agent_sup_sup:start_child().'
|
19
|
+
|
20
|
+
sleep 3
|
data/bin/ci/install_on_debian.sh
CHANGED
@@ -1,17 +1,46 @@
|
|
1
1
|
#!/bin/sh
|
2
2
|
|
3
|
-
sudo apt-get install -y
|
4
|
-
wget -O - "https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc" | sudo apt-key add -
|
3
|
+
sudo apt-get install curl gnupg debian-keyring debian-archive-keyring apt-transport-https -y
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
## Team RabbitMQ's main signing key
|
6
|
+
sudo apt-key adv --keyserver "hkps://keys.openpgp.org" --recv-keys "0x0A9AF2115F4687BD29803A206B73A36E6026DFCA"
|
7
|
+
## Launchpad PPA that provides modern Erlang releases
|
8
|
+
sudo apt-key adv --keyserver "keyserver.ubuntu.com" --recv-keys "F77F1EDA57EBB1CC"
|
9
|
+
## PackageCloud RabbitMQ repository
|
10
|
+
sudo apt-key adv --keyserver "keyserver.ubuntu.com" --recv-keys "F6609E60DC62814E"
|
11
|
+
|
12
|
+
## Add apt repositories maintained by Team RabbitMQ
|
13
|
+
sudo tee /etc/apt/sources.list.d/rabbitmq.list <<EOF
|
14
|
+
## Provides modern Erlang/OTP releases
|
15
|
+
##
|
16
|
+
## "bionic" as distribution name should work for any reasonably recent Ubuntu or Debian release.
|
17
|
+
## See the release to distribution mapping table in RabbitMQ doc guides to learn more.
|
18
|
+
deb http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu bionic main
|
19
|
+
deb-src http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu bionic main
|
20
|
+
|
21
|
+
## Provides RabbitMQ
|
22
|
+
##
|
23
|
+
## "bionic" as distribution name should work for any reasonably recent Ubuntu or Debian release.
|
24
|
+
## See the release to distribution mapping table in RabbitMQ doc guides to learn more.
|
25
|
+
deb https://packagecloud.io/rabbitmq/rabbitmq-server/ubuntu/ bionic main
|
26
|
+
deb-src https://packagecloud.io/rabbitmq/rabbitmq-server/ubuntu/ bionic main
|
9
27
|
EOF
|
10
28
|
|
29
|
+
## Update package indices
|
11
30
|
sudo apt-get update -y
|
12
|
-
|
13
|
-
|
31
|
+
|
32
|
+
## Install Erlang packages
|
33
|
+
sudo apt-get install -y erlang-base \
|
34
|
+
erlang-asn1 erlang-crypto erlang-eldap erlang-ftp erlang-inets \
|
35
|
+
erlang-mnesia erlang-os-mon erlang-parsetools erlang-public-key \
|
36
|
+
erlang-runtime-tools erlang-snmp erlang-ssl \
|
37
|
+
erlang-syntax-tools erlang-tftp erlang-tools erlang-xmerl
|
38
|
+
|
39
|
+
## Install rabbitmq-server and its dependencies
|
40
|
+
sudo apt-get install rabbitmq-server -y --fix-missing
|
14
41
|
|
15
42
|
sudo service rabbitmq-server start
|
16
43
|
|
44
|
+
sudo rabbitmqctl await_startup --timeout 120
|
45
|
+
|
17
46
|
until sudo lsof -i:5672; do echo "Waiting for RabbitMQ to start..."; sleep 1; done
|
data/hutch.gemspec
CHANGED
@@ -6,21 +6,19 @@ Gem::Specification.new do |gem|
|
|
6
6
|
gem.add_runtime_dependency 'march_hare', '>= 3.0.0'
|
7
7
|
else
|
8
8
|
gem.platform = Gem::Platform::RUBY
|
9
|
-
gem.add_runtime_dependency 'bunny', '>= 2.
|
9
|
+
gem.add_runtime_dependency 'bunny', '>= 2.19', '< 3.0'
|
10
10
|
end
|
11
11
|
gem.add_runtime_dependency 'carrot-top', '~> 0.0.7'
|
12
|
-
gem.add_runtime_dependency 'multi_json', '~> 1.
|
13
|
-
gem.add_runtime_dependency 'activesupport', '>= 4.2', '<
|
12
|
+
gem.add_runtime_dependency 'multi_json', '~> 1.15'
|
13
|
+
gem.add_runtime_dependency 'activesupport', '>= 4.2', '< 8'
|
14
14
|
|
15
15
|
gem.name = 'hutch'
|
16
|
-
gem.summary = '
|
17
|
-
gem.description = 'Hutch is a Ruby library for enabling asynchronous '
|
18
|
-
'inter-service communication using RabbitMQ.'
|
16
|
+
gem.summary = 'Opinionated asynchronous inter-service communication using RabbitMQ'
|
17
|
+
gem.description = 'Hutch is a Ruby library for enabling asynchronous inter-service communication using RabbitMQ'
|
19
18
|
gem.version = Hutch::VERSION.dup
|
20
19
|
gem.required_ruby_version = '>= 2.2'
|
21
|
-
gem.authors = ['Harry Marr']
|
22
|
-
gem.
|
23
|
-
gem.homepage = 'https://github.com/gocardless/hutch'
|
20
|
+
gem.authors = ['Harry Marr', 'Michael Klishin']
|
21
|
+
gem.homepage = 'https://github.com/ruby-amqp/hutch'
|
24
22
|
gem.require_paths = ['lib']
|
25
23
|
gem.license = 'MIT'
|
26
24
|
gem.executables = ['hutch']
|
data/lib/hutch/adapters/bunny.rb
CHANGED
@@ -32,6 +32,10 @@ module Hutch
|
|
32
32
|
def current_timestamp
|
33
33
|
Time.now
|
34
34
|
end
|
35
|
+
|
36
|
+
def self.new_exchange(ch, exchange_type, exchange_name, exchange_options)
|
37
|
+
MarchHare::Exchange.new(ch, exchange_name, exchange_options.merge(type: exchange_type))
|
38
|
+
end
|
35
39
|
end
|
36
40
|
end
|
37
41
|
end
|
data/lib/hutch/broker.rb
CHANGED
@@ -122,11 +122,12 @@ module Hutch
|
|
122
122
|
|
123
123
|
def declare_exchange(ch = channel)
|
124
124
|
exchange_name = @config[:mq_exchange]
|
125
|
+
exchange_type = @config[:mq_exchange_type]
|
125
126
|
exchange_options = { durable: true }.merge(@config[:mq_exchange_options])
|
126
127
|
logger.info "using topic exchange '#{exchange_name}'"
|
127
128
|
|
128
129
|
with_bunny_precondition_handler('exchange') do
|
129
|
-
|
130
|
+
Adapter.new_exchange(ch, exchange_type, exchange_name, exchange_options)
|
130
131
|
end
|
131
132
|
end
|
132
133
|
|
@@ -170,11 +171,11 @@ module Hutch
|
|
170
171
|
end
|
171
172
|
|
172
173
|
# Create / get a durable queue and apply namespace if it exists.
|
173
|
-
def queue(name,
|
174
|
+
def queue(name, options = {})
|
174
175
|
with_bunny_precondition_handler('queue') do
|
175
176
|
namespace = @config[:namespace].to_s.downcase.gsub(/[^-_:\.\w]/, "")
|
176
177
|
name = name.prepend(namespace + ":") if namespace.present?
|
177
|
-
channel.queue(name,
|
178
|
+
channel.queue(name, **options)
|
178
179
|
end
|
179
180
|
end
|
180
181
|
|
data/lib/hutch/cli.rb
CHANGED
@@ -40,6 +40,9 @@ module Hutch
|
|
40
40
|
# handlers are set up. Due to this, we never got any Sentry notifications
|
41
41
|
# when an error occurred in any of the consumers.
|
42
42
|
if defined?(Raven)
|
43
|
+
Hutch::Config[:error_handlers] << Hutch::ErrorHandlers::SentryRaven.new
|
44
|
+
end
|
45
|
+
if defined?(Sentry)
|
43
46
|
Hutch::Config[:error_handlers] << Hutch::ErrorHandlers::Sentry.new
|
44
47
|
end
|
45
48
|
|
data/lib/hutch/config.rb
CHANGED
@@ -49,6 +49,9 @@ module Hutch
|
|
49
49
|
# RabbitMQ Exchange to use for publishing
|
50
50
|
string_setting :mq_exchange, 'hutch'
|
51
51
|
|
52
|
+
# RabbitMQ Exchange type to use for publishing
|
53
|
+
string_setting :mq_exchange_type, 'topic'
|
54
|
+
|
52
55
|
# RabbitMQ vhost to use
|
53
56
|
string_setting :mq_vhost, '/'
|
54
57
|
|
@@ -142,6 +145,9 @@ module Hutch
|
|
142
145
|
# Prefix displayed on the consumers tags.
|
143
146
|
string_setting :consumer_tag_prefix, 'hutch'
|
144
147
|
|
148
|
+
# A namespace to help group your queues
|
149
|
+
string_setting :namespace, nil
|
150
|
+
|
145
151
|
string_setting :group, ''
|
146
152
|
|
147
153
|
# Set of all setting keys
|
@@ -190,14 +196,7 @@ module Hutch
|
|
190
196
|
env_keys_configured.each_with_object({}) {|attr, result|
|
191
197
|
value = ENV[key_for(attr)]
|
192
198
|
|
193
|
-
|
194
|
-
when is_bool(attr) || value == 'false'
|
195
|
-
result[attr] = to_bool(value)
|
196
|
-
when is_num(attr)
|
197
|
-
result[attr] = value.to_i
|
198
|
-
else
|
199
|
-
result[attr] = value
|
200
|
-
end
|
199
|
+
result[attr] = type_cast(attr, value)
|
201
200
|
}
|
202
201
|
end
|
203
202
|
|
@@ -232,7 +231,7 @@ module Hutch
|
|
232
231
|
|
233
232
|
def self.set(attr, value)
|
234
233
|
check_attr(attr.to_sym)
|
235
|
-
user_config[attr.to_sym] = value
|
234
|
+
user_config[attr.to_sym] = type_cast(attr, value)
|
236
235
|
end
|
237
236
|
|
238
237
|
class << self
|
@@ -269,6 +268,18 @@ module Hutch
|
|
269
268
|
end
|
270
269
|
end
|
271
270
|
|
271
|
+
def self.type_cast(attr, value)
|
272
|
+
case
|
273
|
+
when is_bool(attr) || value == 'false'
|
274
|
+
to_bool(value)
|
275
|
+
when is_num(attr)
|
276
|
+
value.to_i
|
277
|
+
else
|
278
|
+
value
|
279
|
+
end
|
280
|
+
end
|
281
|
+
private_class_method :type_cast
|
282
|
+
|
272
283
|
def self.define_methods
|
273
284
|
@config.keys.each do |key|
|
274
285
|
define_singleton_method(key) do
|
data/lib/hutch/consumer.rb
CHANGED
@@ -29,8 +29,9 @@ module Hutch
|
|
29
29
|
# wants to subscribe to.
|
30
30
|
def consume(*routing_keys)
|
31
31
|
@routing_keys = self.routing_keys.union(routing_keys)
|
32
|
-
|
33
|
-
@
|
32
|
+
# these are opt-in
|
33
|
+
@queue_mode = nil
|
34
|
+
@queue_type = nil
|
34
35
|
end
|
35
36
|
|
36
37
|
attr_reader :queue_mode, :queue_type, :initial_group_size
|
@@ -45,6 +46,11 @@ module Hutch
|
|
45
46
|
@queue_mode = 'lazy'
|
46
47
|
end
|
47
48
|
|
49
|
+
# Explicitly set the queue type to 'classic'
|
50
|
+
def classic_queue
|
51
|
+
@queue_type = 'classic'
|
52
|
+
end
|
53
|
+
|
48
54
|
# Explicitly set the queue type to 'quorum'
|
49
55
|
# @param [Hash] options the options params related to quorum queue
|
50
56
|
# @option options [Integer] :initial_group_size Initial Replication Factor
|
@@ -53,11 +59,17 @@ module Hutch
|
|
53
59
|
@initial_group_size = options[:initial_group_size]
|
54
60
|
end
|
55
61
|
|
56
|
-
#
|
62
|
+
# Configures an optional argument that will be passed when declaring the queue.
|
63
|
+
# Prefer using a policy to this DSL: https://www.rabbitmq.com/parameters.html#policies
|
57
64
|
def arguments(arguments = {})
|
58
65
|
@arguments = arguments
|
59
66
|
end
|
60
67
|
|
68
|
+
# Congfiures queue options that will be passed when declaring the queue.
|
69
|
+
def queue_options(options = {})
|
70
|
+
@queue_options = options
|
71
|
+
end
|
72
|
+
|
61
73
|
# Set custom serializer class, override global value
|
62
74
|
def serializer(name)
|
63
75
|
@serializer = name
|
@@ -76,14 +88,23 @@ module Hutch
|
|
76
88
|
# Returns consumer custom arguments.
|
77
89
|
def get_arguments
|
78
90
|
all_arguments = @arguments || {}
|
79
|
-
|
80
|
-
all_arguments['x-queue-
|
81
|
-
if @
|
82
|
-
|
83
|
-
|
91
|
+
|
92
|
+
all_arguments['x-queue-mode'] = @queue_mode if @queue_mode
|
93
|
+
all_arguments['x-queue-type'] = @queue_type if @queue_type
|
94
|
+
all_arguments['x-quorum-initial-group-size'] = @initial_group_size if @initial_group_size
|
95
|
+
|
84
96
|
all_arguments
|
85
97
|
end
|
86
98
|
|
99
|
+
def get_options
|
100
|
+
default_options = { durable: true }
|
101
|
+
|
102
|
+
all_options = default_options.merge(@queue_options || {})
|
103
|
+
all_options[:arguments] = get_arguments
|
104
|
+
|
105
|
+
all_options
|
106
|
+
end
|
107
|
+
|
87
108
|
# Accessor for the consumer's routing key.
|
88
109
|
def routing_keys
|
89
110
|
@routing_keys ||= Set.new
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require "hutch/logging"
|
2
|
+
require "bugsnag"
|
3
|
+
require "hutch/error_handlers/base"
|
4
|
+
|
5
|
+
module Hutch
|
6
|
+
module ErrorHandlers
|
7
|
+
class Bugsnag < Base
|
8
|
+
def handle(properties, payload, consumer, ex)
|
9
|
+
message_id = properties.message_id
|
10
|
+
prefix = "message(#{message_id || "-"}):"
|
11
|
+
logger.error "#{prefix} Logging event to Bugsnag"
|
12
|
+
logger.error "#{prefix} #{ex.class} - #{ex.message}"
|
13
|
+
|
14
|
+
::Bugsnag.notify(ex) do |report|
|
15
|
+
report.add_tab(:hutch, {
|
16
|
+
payload: payload,
|
17
|
+
consumer: consumer
|
18
|
+
})
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def handle_setup_exception(ex)
|
23
|
+
logger.error "Logging setup exception to Bugsnag"
|
24
|
+
logger.error "#{ex.class} - #{ex.message}"
|
25
|
+
|
26
|
+
::Bugsnag.notify(ex)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|