hutch 1.3.1 → 2.0.0.rc1
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/CHANGELOG.md +111 -7
- data/LICENSE +1 -1
- data/README.md +42 -42
- data/bin/ci/before_build_docker.sh +2 -7
- data/lib/hutch/acknowledgements/nack_on_all_failures.rb +1 -1
- data/lib/hutch/adapters/bunny.rb +25 -1
- data/lib/hutch/adapters/march_hare.rb +21 -1
- data/lib/hutch/broker.rb +82 -27
- data/lib/hutch/cli.rb +1 -4
- data/lib/hutch/config.rb +3 -3
- data/lib/hutch/consumer.rb +12 -3
- data/lib/hutch/error_handlers.rb +0 -1
- data/lib/hutch/serializers/json.rb +3 -3
- data/lib/hutch/tracers/datadog.rb +2 -2
- data/lib/hutch/version.rb +1 -1
- data/lib/hutch/worker.rb +43 -6
- data/lib/yard-settings/yard-settings.rb +2 -2
- data/spec/hutch/broker_spec.rb +189 -11
- data/spec/hutch/cli_spec.rb +12 -9
- data/spec/hutch/consumer_spec.rb +11 -0
- data/spec/hutch/error_handlers/airbrake_spec.rb +4 -1
- data/spec/hutch/error_handlers/bugsnag_spec.rb +1 -1
- data/spec/hutch/error_handlers/honeybadger_spec.rb +1 -1
- data/spec/hutch/error_handlers/logger_spec.rb +1 -1
- data/spec/hutch/error_handlers/rollbar_spec.rb +1 -1
- data/spec/hutch/error_handlers/sentry_spec.rb +1 -1
- data/spec/hutch/message_spec.rb +1 -1
- data/spec/hutch/tracers/datadog_spec.rb +1 -1
- data/spec/hutch/worker_spec.rb +82 -12
- data/spec/integration/channel_recovery_spec.rb +187 -0
- data/spec/integration/publish_consume_spec.rb +47 -0
- metadata +12 -41
- data/.github/workflows/test.yml +0 -56
- data/.gitignore +0 -10
- data/.rspec +0 -1
- data/.yardopts +0 -5
- data/Gemfile +0 -35
- data/Guardfile +0 -14
- data/Rakefile +0 -21
- data/examples/consumer.rb +0 -13
- data/examples/producer.rb +0 -10
- data/hutch.gemspec +0 -27
- data/lib/hutch/error_handlers/sentry_raven.rb +0 -31
- data/spec/hutch/error_handlers/sentry_raven_spec.rb +0 -37
- data/spec/spec_helper.rb +0 -42
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8978faf08cf85e68cc957d91ff3059b0b3fecb73e018a80ec551c9547be9c99a
|
|
4
|
+
data.tar.gz: 2c1f461463321e705e2464373093135bf307b68dac9f08b284e8c5f6c9e710db
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8900ac9233d8849f789b2f598e8109d8bcc7aab3bc7870c00d881e47aaa6f3a3722b906a018c8c8f6dd0b69258a15f7f7654027a216429a9bfe2639f53070100
|
|
7
|
+
data.tar.gz: e3c8b5ac42f24483a773167eb79d01e9e29e71859c0a78ccf01d59b018ec1f57a1a5c26c8da47ad9ebb743b04fed9d67989802eb0f495bd894c1b3c51cb830c3
|
data/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,112 @@
|
|
|
1
|
-
|
|
1
|
+
# Hutch Change Log
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## 2.0.0 (TBD)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
### Breaking Changes
|
|
6
|
+
|
|
7
|
+
* Ruby `3.2` or JRuby `10` is now required
|
|
8
|
+
* The Datadog tracer now depends on the [`datadog`](https://github.com/DataDog/dd-trace-rb)
|
|
9
|
+
gem, which replaces the EOL `ddtrace`
|
|
10
|
+
([migration guide](https://github.com/DataDog/dd-trace-rb/blob/master/docs/UpgradeGuide2.md))
|
|
11
|
+
* `Hutch::ErrorHandlers::SentryRaven` has been replaced by
|
|
12
|
+
`Hutch::ErrorHandlers::Sentry`, backed by `sentry-ruby`
|
|
13
|
+
([migration guide](https://docs.sentry.io/platforms/ruby/migration/))
|
|
14
|
+
* Messages are serialized with the stdlib `json` instead of `multi_json`, which
|
|
15
|
+
means that `MultiJson` configuration such as `MultiJson.use(:oj)` no longer
|
|
16
|
+
affects Hutch
|
|
17
|
+
|
|
18
|
+
### Consumer Recovery After a RabbitMQ 4.3 Quorum Queue Consumer Timeout
|
|
19
|
+
|
|
20
|
+
RabbitMQ 4.3 quorum queues cancel a timed out consumer with `basic.cancel`
|
|
21
|
+
instead of closing the channel. Hutch 1.4.0 does not react to that, so on 4.3
|
|
22
|
+
a consumer stops consuming its queue until the worker restarts.
|
|
23
|
+
|
|
24
|
+
Workers now re-subscribe consumers cancelled by the server, but only if
|
|
25
|
+
the queue still exists: a `basic.cancel` carries no reason, so a consumer
|
|
26
|
+
timeout is indistinguishable from a queue deletion. The consumer channel is
|
|
27
|
+
replaced in the process, so the deliveries the cancelled consumer still held
|
|
28
|
+
are requeued instead of dropped.
|
|
29
|
+
|
|
30
|
+
Handlers that are still running get a graceful exit to finish before
|
|
31
|
+
the old channel is closed, and their acknowledgements are dropped rather than
|
|
32
|
+
sent on the new channel, where their delivery tags mean nothing.
|
|
33
|
+
|
|
34
|
+
### Connection URIs Are Now Percent-Decoded
|
|
35
|
+
|
|
36
|
+
The virtual host, username and password of a connection URI are now decoded, as
|
|
37
|
+
[the URI specification](https://www.rabbitmq.com/docs/uri-spec) requires.
|
|
38
|
+
`amqp://host/%2F` connects to the default virtual host instead of one literally
|
|
39
|
+
named `%2F`, and credentials containing a space, `#` or `@` authenticate again.
|
|
40
|
+
|
|
41
|
+
Reported by @deissimon.
|
|
42
|
+
|
|
43
|
+
GitHub issue: [#422](https://github.com/ruby-amqp/hutch/issues/422)
|
|
44
|
+
|
|
45
|
+
### Fixed Two JRuby Regressions
|
|
46
|
+
|
|
47
|
+
Opening a channel raised, and the `march_hare` adapter did not declare the
|
|
48
|
+
exchange it instantiated.
|
|
49
|
+
|
|
50
|
+
GitHub issue: [#427](https://github.com/ruby-amqp/hutch/issues/427)
|
|
51
|
+
|
|
52
|
+
### The JRuby Variant Is Revived
|
|
53
|
+
|
|
54
|
+
The `java` platform gem, which depends on March Hare instead of Bunny, was last
|
|
55
|
+
published as `0.25.0` in January 2018 and has seen little more than CI version
|
|
56
|
+
bumps since. This release requires JRuby `10` and `march_hare` `4.7.0`, adds a
|
|
57
|
+
JRuby CI job, and publishes the gem again.
|
|
58
|
+
|
|
59
|
+
Recovering a channel the broker closed remains Bunny-only: `MarchHare::Channel`
|
|
60
|
+
has no `on_error` callback and no `reopen`.
|
|
61
|
+
|
|
62
|
+
## 1.4.0 (Apr 7, 2026)
|
|
63
|
+
|
|
64
|
+
### Ruby 3.0 is Now Required
|
|
65
|
+
|
|
66
|
+
This version adopts [Bunny `3.x`](https://github.com/ruby-amqp/bunny/releases/tag/3.0.0)
|
|
67
|
+
and as a result, requires Ruby 3.0.
|
|
68
|
+
|
|
69
|
+
### `without_namespace` Consumer DSL Option
|
|
70
|
+
|
|
71
|
+
Consumers can now opt out of the automatic namespace prefix
|
|
72
|
+
for their queue name using the `without_namespace` DSL method:
|
|
73
|
+
|
|
74
|
+
``` ruby
|
|
75
|
+
class DeadLetterConsumer
|
|
76
|
+
include Hutch::Consumer
|
|
77
|
+
consume 'dead.letters'
|
|
78
|
+
queue_name 'deadletter'
|
|
79
|
+
without_namespace
|
|
80
|
+
end
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Originally contributed by @tlloydthwaites.
|
|
84
|
+
|
|
85
|
+
GitHub issue: [#393](https://github.com/ruby-amqp/hutch/pull/393)
|
|
86
|
+
|
|
87
|
+
### Consumer Channel Recovery After Delivery Acknowledgement Timeout
|
|
88
|
+
|
|
89
|
+
Hutch now automatically "recovers" (reopens) consumer channels closed by RabbitMQ
|
|
90
|
+
due to a [delivery acknowledgement timeout](https://www.rabbitmq.com/docs/consumers#acknowledgement-timeout).
|
|
91
|
+
|
|
92
|
+
Note that this exception indicates a potential issue on Hutch's end:
|
|
93
|
+
a delivery was not acknowledged in time (30 minutes by default). Even then,
|
|
94
|
+
recovering the channel in this specific scenario is an operational improvement.
|
|
95
|
+
|
|
96
|
+
Contributed by @Garaio-REM.
|
|
97
|
+
|
|
98
|
+
GitHub issue: [#414](https://github.com/ruby-amqp/hutch/pull/414)
|
|
99
|
+
|
|
100
|
+
### Migrated Datadog Tracer From the `ddtrace` Gem to `datadog`
|
|
101
|
+
|
|
102
|
+
The Datadog tracer now uses the `datadog` gem instead of the deprecated `ddtrace`.
|
|
103
|
+
The `ddtrace` gem is still supported but emits a deprecation warning at load time.
|
|
104
|
+
Support for `ddtrace` will be removed in Hutch 2.0.
|
|
105
|
+
|
|
106
|
+
### Deprecated `SentryRaven` Error Handler
|
|
107
|
+
|
|
108
|
+
`Hutch::ErrorHandlers::SentryRaven` now emits a deprecation warning and will be
|
|
109
|
+
removed in Hutch 2.0. Use `Hutch::ErrorHandlers::Sentry` (backed by `sentry-ruby`) instead.
|
|
6
110
|
|
|
7
111
|
### Rails 8.x Compatibility
|
|
8
112
|
|
|
@@ -19,7 +123,7 @@ GitHub issue: [#392](https://github.com/ruby-amqp/hutch/pull/392)
|
|
|
19
123
|
|
|
20
124
|
### Relaxed ActiveSupport Dependency Constraints
|
|
21
125
|
|
|
22
|
-
Contributed by
|
|
126
|
+
Contributed by drobny.
|
|
23
127
|
|
|
24
128
|
GitHub issue: [#402](https://github.com/ruby-amqp/hutch/pull/402)
|
|
25
129
|
|
|
@@ -93,7 +197,7 @@ contains potentially breaking changes.
|
|
|
93
197
|
|
|
94
198
|
This means **some defaults introduced in `0.28.0` ([gocardless/hutch#341](https://github.com/gocardless/hutch/pull/341)) were reverted**.
|
|
95
199
|
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.
|
|
96
|
-
Most optional arguments can be set via [policies](https://www.rabbitmq.com/parameters.html#policies) which is always the recommended approach.
|
|
200
|
+
Most optional arguments can be set via [policies](https://www.rabbitmq.com/parameters.html#policies) which is always the recommended approach.
|
|
97
201
|
Queue type, unfortunately, is not one of them as different queue types have completely different
|
|
98
202
|
implementation details, on disk data formats and so on.
|
|
99
203
|
|
|
@@ -106,7 +210,7 @@ contains potentially breaking changes.
|
|
|
106
210
|
# when in doubt, prefer using a policy to this DSL
|
|
107
211
|
# https://www.rabbitmq.com/parameters.html#policies
|
|
108
212
|
arguments 'x-key': :value
|
|
109
|
-
|
|
213
|
+
|
|
110
214
|
quorum_queue
|
|
111
215
|
end
|
|
112
216
|
```
|
|
@@ -120,7 +224,7 @@ contains potentially breaking changes.
|
|
|
120
224
|
# when in doubt, prefer using a policy to this DSL
|
|
121
225
|
# https://www.rabbitmq.com/parameters.html#policies
|
|
122
226
|
arguments 'x-key': :value
|
|
123
|
-
|
|
227
|
+
|
|
124
228
|
lazy_queue
|
|
125
229
|
classic_queue
|
|
126
230
|
end
|
data/LICENSE
CHANGED
data/README.md
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
](http://badge.fury.io/rb/hutch)
|
|
4
|
-
[](https://codeclimate.com/github/gocardless/hutch)
|
|
1
|
+
[](https://badge.fury.io/rb/hutch)
|
|
2
|
+
[](https://github.com/ruby-amqp/hutch/actions/workflows/test.yml)
|
|
5
3
|
|
|
6
4
|
Hutch is a Ruby library for enabling asynchronous inter-service communication
|
|
7
5
|
in a service-oriented architecture, using RabbitMQ.
|
|
@@ -23,6 +21,8 @@ gem install hutch
|
|
|
23
21
|
- [Message Processing Tracers](#message-processing-tracers)
|
|
24
22
|
- [Running Hutch](#running-hutch)
|
|
25
23
|
- [Loading Consumers](#loading-consumers)
|
|
24
|
+
- [Consumer Groups](#consumer-groups)
|
|
25
|
+
- [Loading Consumers Manually (One-by-One)](#loading-consumers-manually-one-by-one)
|
|
26
26
|
- [Stopping Hutch](#stopping-hutch)
|
|
27
27
|
- [Producers](#producers)
|
|
28
28
|
- [Producer Configuration](#producer-configuration)
|
|
@@ -38,8 +38,8 @@ gem install hutch
|
|
|
38
38
|
|
|
39
39
|
## Requirements
|
|
40
40
|
|
|
41
|
-
- Hutch requires Ruby 2
|
|
42
|
-
- Hutch requires RabbitMQ 3.
|
|
41
|
+
- Hutch requires Ruby 3.2+ or JRuby 10+
|
|
42
|
+
- Hutch requires RabbitMQ 3.13 or later
|
|
43
43
|
|
|
44
44
|
## Overview
|
|
45
45
|
|
|
@@ -52,7 +52,7 @@ With Hutch, consumers are stored in separate files and include the `Hutch::Consu
|
|
|
52
52
|
They are then loaded by a command line runner which connects to RabbitMQ, sets up queues and bindings,
|
|
53
53
|
and so on. Publishers connect to RabbitMQ via `Hutch.connect` and publish using `Hutch.publish`.
|
|
54
54
|
|
|
55
|
-
Hutch uses [Bunny](
|
|
55
|
+
Hutch uses [Bunny](https://github.com/ruby-amqp/bunny) or [March Hare](https://github.com/ruby-amqp/march_hare)
|
|
56
56
|
(on JRuby) under the hood.
|
|
57
57
|
|
|
58
58
|
### Project Maturity
|
|
@@ -79,7 +79,7 @@ message[:id] # => "02ABCXYZ"
|
|
|
79
79
|
To subscribe to a topic, pass a routing key to `consume` in the class
|
|
80
80
|
definition. To bind to multiple routing keys, simply pass extra routing keys
|
|
81
81
|
in as additional arguments. Refer to the [RabbitMQ docs on topic exchanges
|
|
82
|
-
](
|
|
82
|
+
](https://www.rabbitmq.com/tutorials/tutorial-five-ruby) for more information
|
|
83
83
|
about how to use routing keys. Here's an example consumer:
|
|
84
84
|
|
|
85
85
|
```ruby
|
|
@@ -110,10 +110,10 @@ end
|
|
|
110
110
|
|
|
111
111
|
It is possible to set some custom options to consumer's queue explicitly.
|
|
112
112
|
This example sets the consumer's queue as a
|
|
113
|
-
[quorum queue](https://www.rabbitmq.com/quorum-queues
|
|
114
|
-
and to operate in the [lazy mode](https://www.rabbitmq.com/lazy-queues
|
|
113
|
+
[quorum queue](https://www.rabbitmq.com/docs/quorum-queues)
|
|
114
|
+
and to operate in the [lazy mode](https://www.rabbitmq.com/docs/lazy-queues).
|
|
115
115
|
The `initial_group_size`
|
|
116
|
-
[argument](https://www.rabbitmq.com/quorum-queues
|
|
116
|
+
[argument](https://www.rabbitmq.com/docs/quorum-queues#replication-factor) is
|
|
117
117
|
optional.
|
|
118
118
|
|
|
119
119
|
```ruby
|
|
@@ -142,11 +142,11 @@ end
|
|
|
142
142
|
```
|
|
143
143
|
|
|
144
144
|
This sets the `x-max-length` header. For more details, see the [RabbitMQ
|
|
145
|
-
documentation on Queue Length Limit](https://www.rabbitmq.com/maxlength
|
|
146
|
-
about custom queue arguments, consult the [RabbitMQ documentation on AMQP Protocol Extensions](https://www.rabbitmq.com/extensions
|
|
145
|
+
documentation on Queue Length Limit](https://www.rabbitmq.com/docs/maxlength). To find out more
|
|
146
|
+
about custom queue arguments, consult the [RabbitMQ documentation on AMQP Protocol Extensions](https://www.rabbitmq.com/docs/extensions).
|
|
147
147
|
|
|
148
148
|
Consumers can write to Hutch's log by calling the logger method. The logger method returns
|
|
149
|
-
a [Logger object](
|
|
149
|
+
a [Logger object](https://docs.ruby-lang.org/en/3.0/Logger.html).
|
|
150
150
|
|
|
151
151
|
```ruby
|
|
152
152
|
class FailedPaymentConsumer
|
|
@@ -174,7 +174,7 @@ client_logger = Logger.new("/path/to/bunny.log")
|
|
|
174
174
|
Hutch::Config.set(:client_logger, client_logger)
|
|
175
175
|
```
|
|
176
176
|
|
|
177
|
-
See this [RabbitMQ tutorial on topic exchanges](
|
|
177
|
+
See this [RabbitMQ tutorial on topic exchanges](https://www.rabbitmq.com/tutorials/tutorial-five-ruby)
|
|
178
178
|
to learn more.
|
|
179
179
|
|
|
180
180
|
### Message Processing Tracers
|
|
@@ -206,7 +206,7 @@ usage: hutch [options]
|
|
|
206
206
|
--mq-host HOST Set the RabbitMQ host
|
|
207
207
|
--mq-port PORT Set the RabbitMQ port
|
|
208
208
|
-t, --[no-]mq-tls Use TLS for the AMQP connection
|
|
209
|
-
--mq-tls-cert FILE Certificate
|
|
209
|
+
--mq-tls-cert FILE Certificate for TLS client verification
|
|
210
210
|
--mq-tls-key FILE Private key for TLS client verification
|
|
211
211
|
--mq-exchange EXCHANGE Set the RabbitMQ exchange
|
|
212
212
|
--mq-vhost VHOST Set the RabbitMQ vhost
|
|
@@ -242,13 +242,13 @@ in the config file, allowing for easy customization.
|
|
|
242
242
|
|
|
243
243
|
Using Hutch with a Rails app is simple. Either start Hutch in the working
|
|
244
244
|
directory of a Rails app, or pass the path to a Rails app in with the
|
|
245
|
-
`--require` option. Consumers defined in Rails apps should be placed
|
|
245
|
+
`--require` option. Consumers defined in Rails apps should be placed within
|
|
246
246
|
the `app/consumers/` directory, to allow them to be auto-loaded when Rails
|
|
247
247
|
boots.
|
|
248
248
|
|
|
249
|
-
If you're using the
|
|
250
|
-
and the consumers are not loaded in development environment you will need to
|
|
251
|
-
trigger
|
|
249
|
+
If you're using the Zeitwerk autoloader (the default since Rails 6)
|
|
250
|
+
and the consumers are not loaded in the development environment, you will need to
|
|
251
|
+
trigger eager loading in an initializer with
|
|
252
252
|
|
|
253
253
|
```ruby
|
|
254
254
|
::Zeitwerk::Loader.eager_load_all
|
|
@@ -309,8 +309,6 @@ kill -SIGTERM 456 # or kill -15 456
|
|
|
309
309
|
kill -SIGQUIT 789 # or kill -3 789
|
|
310
310
|
```
|
|
311
311
|
|
|
312
|
-

|
|
313
|
-
|
|
314
312
|
## Producers
|
|
315
313
|
|
|
316
314
|
Hutch includes a `publish` method for sending messages to Hutch consumers. When
|
|
@@ -334,7 +332,7 @@ Hutch::Config.set(:mq_exchange, 'name')
|
|
|
334
332
|
### Publisher Confirms
|
|
335
333
|
|
|
336
334
|
For maximum message reliability when producing messages, you can force Hutch to use
|
|
337
|
-
[Publisher Confirms](https://www.rabbitmq.com/confirms
|
|
335
|
+
[Publisher Confirms](https://www.rabbitmq.com/docs/confirms) and wait for a confirmation
|
|
338
336
|
after every message published. This is the safest possible option for publishers
|
|
339
337
|
but also results in a **significant throughput drop**.
|
|
340
338
|
|
|
@@ -354,25 +352,27 @@ send messages to Hutch.
|
|
|
354
352
|
- Hutch works with topic exchanges, check the producer is also using topic
|
|
355
353
|
exchanges.
|
|
356
354
|
- Use message routing keys that match those used in your Hutch consumers.
|
|
357
|
-
- Be sure your exchanges are marked as durable
|
|
358
|
-
|
|
359
|
-
- Publish messages as persistent
|
|
360
|
-
- Using publisher confirms is highly recommended
|
|
355
|
+
- Be sure your exchanges are marked as durable, by passing `durable: true`
|
|
356
|
+
to the exchange creation method
|
|
357
|
+
- Publish messages as persistent
|
|
358
|
+
- Using publisher confirms is highly recommended
|
|
361
359
|
|
|
362
360
|
Here's an example of a well-behaved publisher, minus publisher confirms:
|
|
363
361
|
|
|
364
362
|
```ruby
|
|
365
|
-
|
|
366
|
-
channel = AMQP::Channel.new(connection)
|
|
367
|
-
exchange = channel.topic(config[:exchange], durable: true)
|
|
363
|
+
require 'bunny'
|
|
368
364
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
end
|
|
372
|
-
```
|
|
365
|
+
conn = Bunny.new(host: config[:host])
|
|
366
|
+
conn.start
|
|
373
367
|
|
|
374
|
-
|
|
375
|
-
|
|
368
|
+
ch = conn.create_channel
|
|
369
|
+
exchange = ch.topic(config[:exchange], durable: true)
|
|
370
|
+
|
|
371
|
+
message = JSON.dump({ subject: 'Test', id: 'abc' })
|
|
372
|
+
exchange.publish(message, routing_key: 'test', persistent: true)
|
|
373
|
+
|
|
374
|
+
conn.close
|
|
375
|
+
```
|
|
376
376
|
|
|
377
377
|
## Configuration
|
|
378
378
|
|
|
@@ -385,7 +385,7 @@ Known configuration parameters are:
|
|
|
385
385
|
* `mq_host`: RabbitMQ hostname (default: `localhost`)
|
|
386
386
|
* `mq_port`: RabbitMQ port (default: `5672`)
|
|
387
387
|
* `mq_vhost`: vhost to use (default: `/`)
|
|
388
|
-
* `mq_username`: username to use (default: `guest`, only
|
|
388
|
+
* `mq_username`: username to use (default: `guest`, can only connect from localhost)
|
|
389
389
|
* `mq_password`: password to use (default: `guest`)
|
|
390
390
|
* `mq_tls`: should TLS be used? (default: `false`)
|
|
391
391
|
* `mq_tls_cert`: path to client TLS certificate (public key)
|
|
@@ -407,7 +407,7 @@ Known configuration parameters are:
|
|
|
407
407
|
exception happens, see classes in `Hutch::Acknowledgements`.
|
|
408
408
|
* `mq_exchange`: exchange to use for publishing (default: `hutch`)
|
|
409
409
|
* `mq_client_properties`: Bunny's [client properties](https://www.rabbitmq.com/docs/connections#capabilities) (default: `{}`)
|
|
410
|
-
* `heartbeat`: [RabbitMQ heartbeat timeout](
|
|
410
|
+
* `heartbeat`: [RabbitMQ heartbeat timeout](https://www.rabbitmq.com/docs/heartbeats) (default: `30`)
|
|
411
411
|
* `connection_timeout`: Bunny's socket open timeout (default: `11`)
|
|
412
412
|
* `read_timeout`: Bunny's socket read timeout (default: `11`)
|
|
413
413
|
* `write_timeout`: Bunny's socket write timeout (default: `11`)
|
|
@@ -534,7 +534,7 @@ Generate with
|
|
|
534
534
|
<td>30</td>
|
|
535
535
|
<td>Number</td>
|
|
536
536
|
<td><tt>HUTCH_HEARTBEAT</tt></td>
|
|
537
|
-
<td><p><a href="
|
|
537
|
+
<td><p><a href="https://www.rabbitmq.com/docs/heartbeats">RabbitMQ heartbeat timeout</a></p></td>
|
|
538
538
|
</tr>
|
|
539
539
|
<tr>
|
|
540
540
|
<td><tt>channel_prefetch</tt></td>
|
|
@@ -590,7 +590,7 @@ Generate with
|
|
|
590
590
|
<td>11</td>
|
|
591
591
|
<td>Number</td>
|
|
592
592
|
<td><tt>HUTCH_GRACEFUL_EXIT_TIMEOUT</tt></td>
|
|
593
|
-
<td><p>
|
|
593
|
+
<td><p>Timeout (in seconds) for consumer threads to finish before being killed during graceful shutdown</p></td>
|
|
594
594
|
</tr>
|
|
595
595
|
<tr>
|
|
596
596
|
<td><tt>consumer_pool_size</tt></td>
|
|
@@ -646,7 +646,7 @@ Generate with
|
|
|
646
646
|
<td>false</td>
|
|
647
647
|
<td>Boolean</td>
|
|
648
648
|
<td><tt>HUTCH_FORCE_PUBLISHER_CONFIRMS</tt></td>
|
|
649
|
-
<td><p>Enables publisher confirms, forces Hutch::Broker#wait_for_confirms for</p></td>
|
|
649
|
+
<td><p>Enables publisher confirms, forces Hutch::Broker#wait_for_confirms for every publish</p></td>
|
|
650
650
|
</tr>
|
|
651
651
|
<tr>
|
|
652
652
|
<td><tt>enable_http_api_use</tt></td>
|
|
@@ -681,7 +681,7 @@ Generate with
|
|
|
681
681
|
<td>''</td>
|
|
682
682
|
<td>String</td>
|
|
683
683
|
<td><tt>HUTCH_GROUP</tt></td>
|
|
684
|
-
<td></td>
|
|
684
|
+
<td><p>Consumer group to load (see Consumer Groups)</p></td>
|
|
685
685
|
</tr>
|
|
686
686
|
</tbody>
|
|
687
687
|
</table>
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
#!/bin/sh
|
|
2
2
|
|
|
3
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
4
|
|
|
10
5
|
# guest:guest has full access to /
|
|
11
6
|
|
|
@@ -14,7 +9,7 @@ $CTL add_vhost /
|
|
|
14
9
|
$CTL set_permissions -p / guest ".*" ".*" ".*"
|
|
15
10
|
|
|
16
11
|
# 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().'
|
|
12
|
+
$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().' || true
|
|
13
|
+
$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().' || true
|
|
19
14
|
|
|
20
15
|
sleep 3
|
data/lib/hutch/adapters/bunny.rb
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
require 'bunny'
|
|
2
2
|
require 'forwardable'
|
|
3
3
|
|
|
4
|
+
require 'hutch/logging'
|
|
5
|
+
|
|
4
6
|
module Hutch
|
|
5
7
|
module Adapters
|
|
6
8
|
class BunnyAdapter
|
|
7
9
|
extend Forwardable
|
|
10
|
+
include Logging
|
|
8
11
|
|
|
9
12
|
DEFAULT_VHOST = Bunny::Session::DEFAULT_VHOST
|
|
10
13
|
|
|
11
14
|
ConnectionRefused = Bunny::TCPConnectionFailed
|
|
15
|
+
ChannelAlreadyClosed = Bunny::ChannelAlreadyClosed
|
|
12
16
|
PreconditionFailed = Bunny::PreconditionFailed
|
|
13
17
|
|
|
14
|
-
def_delegators :@connection, :start, :disconnect, :close, :create_channel, :open
|
|
18
|
+
def_delegators :@connection, :start, :disconnect, :close, :create_channel, :open?, :recover_channel_topology
|
|
15
19
|
|
|
16
20
|
def initialize(opts={})
|
|
17
21
|
@connection = Bunny.new(opts)
|
|
@@ -25,6 +29,26 @@ module Hutch
|
|
|
25
29
|
ch.prefetch(prefetch) if prefetch
|
|
26
30
|
end
|
|
27
31
|
|
|
32
|
+
def queue_exists?(name)
|
|
33
|
+
@connection.queue_exists?(name)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def install_channel_recovery(ch)
|
|
37
|
+
# A consumer timeout invalidates the delivery tag, so a handler that
|
|
38
|
+
# was still running acknowledges an unknown tag and closes the channel.
|
|
39
|
+
ch.on_error do |channel, close|
|
|
40
|
+
next unless close.delivery_ack_timeout? || close.unknown_delivery_tag?
|
|
41
|
+
|
|
42
|
+
begin
|
|
43
|
+
channel.reopen
|
|
44
|
+
recover_channel_topology(channel)
|
|
45
|
+
logger.warn "recovered consumer channel closed with '#{close.reply_text}'"
|
|
46
|
+
rescue => ex
|
|
47
|
+
logger.error "channel recovery failed: #{ex.class}: #{ex.message}"
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
28
52
|
def current_timestamp
|
|
29
53
|
Time.now.to_i
|
|
30
54
|
end
|
|
@@ -9,6 +9,7 @@ module Hutch
|
|
|
9
9
|
DEFAULT_VHOST = "/"
|
|
10
10
|
|
|
11
11
|
ConnectionRefused = MarchHare::ConnectionRefused
|
|
12
|
+
ChannelAlreadyClosed = MarchHare::ChannelAlreadyClosed
|
|
12
13
|
PreconditionFailed = MarchHare::PreconditionFailed
|
|
13
14
|
|
|
14
15
|
def_delegators :@connection, :start, :disconnect, :close, :open?
|
|
@@ -25,6 +26,25 @@ module Hutch
|
|
|
25
26
|
ch.prefetch = prefetch if prefetch
|
|
26
27
|
end
|
|
27
28
|
|
|
29
|
+
# `MarchHare::Session` has no `queue_exists?` counterpart, and a failed
|
|
30
|
+
# passive declare closes the channel, hence the throwaway one.
|
|
31
|
+
def queue_exists?(name)
|
|
32
|
+
ch = @connection.create_channel
|
|
33
|
+
begin
|
|
34
|
+
ch.queue(name, passive: true)
|
|
35
|
+
true
|
|
36
|
+
rescue MarchHare::NotFound
|
|
37
|
+
false
|
|
38
|
+
ensure
|
|
39
|
+
ch.close rescue nil
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# MarchHare::Channel has no on_error callback, and neither Channel#reopen
|
|
44
|
+
# nor Session#recover_channel_topology has a `march_hare` counterpart.
|
|
45
|
+
def install_channel_recovery(ch)
|
|
46
|
+
end
|
|
47
|
+
|
|
28
48
|
def create_channel(n = nil, consumer_pool_size = 1, consumer_pool_abort_on_exception = false)
|
|
29
49
|
@connection.create_channel(n)
|
|
30
50
|
end
|
|
@@ -34,7 +54,7 @@ module Hutch
|
|
|
34
54
|
end
|
|
35
55
|
|
|
36
56
|
def self.new_exchange(ch, exchange_type, exchange_name, exchange_options)
|
|
37
|
-
MarchHare::Exchange.new(ch, exchange_name, exchange_options.merge(type: exchange_type))
|
|
57
|
+
MarchHare::Exchange.new(ch, exchange_name, exchange_options.merge(type: exchange_type)).tap(&:declare!)
|
|
38
58
|
end
|
|
39
59
|
end
|
|
40
60
|
end
|