hutch 0.25.0-java → 2.0.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 +4 -4
- data/CHANGELOG.md +402 -5
- data/LICENSE +1 -0
- data/README.md +157 -47
- data/bin/ci/before_build.sh +20 -0
- data/bin/ci/before_build_docker.sh +15 -0
- data/bin/ci/install_on_debian.sh +46 -0
- data/lib/hutch/acknowledgements/nack_on_all_failures.rb +1 -1
- data/lib/hutch/adapters/bunny.rb +29 -1
- data/lib/hutch/adapters/march_hare.rb +24 -0
- data/lib/hutch/broker.rb +98 -35
- data/lib/hutch/cli.rb +16 -12
- data/lib/hutch/config.rb +42 -13
- data/lib/hutch/consumer.rb +63 -4
- data/lib/hutch/error_handlers/bugsnag.rb +30 -0
- data/lib/hutch/error_handlers/{opbeat.rb → rollbar.rb} +11 -13
- data/lib/hutch/error_handlers/sentry.rb +6 -11
- data/lib/hutch/error_handlers.rb +2 -1
- data/lib/hutch/publisher.rb +1 -1
- data/lib/hutch/serializers/json.rb +3 -3
- data/lib/hutch/tracers/datadog.rb +18 -0
- data/lib/hutch/tracers.rb +1 -1
- data/lib/hutch/version.rb +1 -2
- data/lib/hutch/worker.rb +46 -9
- data/lib/hutch.rb +8 -4
- data/lib/yard-settings/yard-settings.rb +2 -2
- data/spec/hutch/broker_spec.rb +192 -14
- data/spec/hutch/cli_spec.rb +12 -9
- data/spec/hutch/config_spec.rb +84 -12
- data/spec/hutch/consumer_spec.rb +93 -4
- data/spec/hutch/error_handlers/airbrake_spec.rb +4 -1
- data/spec/hutch/error_handlers/bugsnag_spec.rb +56 -0
- 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 +45 -0
- data/spec/hutch/error_handlers/sentry_spec.rb +13 -3
- data/spec/hutch/message_spec.rb +1 -1
- data/spec/hutch/tracers/datadog_spec.rb +46 -0
- data/spec/hutch/waiter_spec.rb +2 -2
- data/spec/hutch/worker_spec.rb +138 -24
- data/spec/integration/channel_recovery_spec.rb +187 -0
- data/spec/integration/publish_consume_spec.rb +47 -0
- metadata +32 -59
- data/.gitignore +0 -10
- data/.rspec +0 -1
- data/.travis.yml +0 -16
- data/.yardopts +0 -5
- data/Gemfile +0 -33
- data/Guardfile +0 -14
- data/Rakefile +0 -21
- data/examples/consumer.rb +0 -13
- data/examples/producer.rb +0 -10
- data/hutch.gemspec +0 -29
- data/lib/hutch/tracers/opbeat.rb +0 -37
- data/spec/hutch/error_handlers/opbeat_spec.rb +0 -37
- data/spec/spec_helper.rb +0 -42
- data/spec/tracers/opbeat_spec.rb +0 -44
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
# Channel recovery is bunny-only, see MarchHareAdapter#install_channel_recovery
|
|
4
|
+
return if defined?(JRUBY_VERSION)
|
|
5
|
+
require 'hutch/broker'
|
|
6
|
+
require 'hutch/worker'
|
|
7
|
+
require 'hutch/consumer'
|
|
8
|
+
require 'bunny'
|
|
9
|
+
require 'json'
|
|
10
|
+
require 'securerandom'
|
|
11
|
+
|
|
12
|
+
describe 'channel recovery after delivery acknowledgement timeout', rabbitmq: true, adapter: :bunny do
|
|
13
|
+
CONSUMER_TIMEOUT_MS = 5_000
|
|
14
|
+
# A 4.3 quorum queue times the consumer out on its own timer, which fires at
|
|
15
|
+
# the deadline. Earlier series detect it from the channel tick instead, and
|
|
16
|
+
# `channel_tick_interval` defaults to 60s, so detection lags by up to that much.
|
|
17
|
+
BLOCKED_HANDLER_SECONDS = 20
|
|
18
|
+
BLOCKED_HANDLER_SECONDS_BEFORE_4_3 = 100
|
|
19
|
+
|
|
20
|
+
let(:log) { StringIO.new }
|
|
21
|
+
let(:logger) { Logger.new(log) }
|
|
22
|
+
let(:exchange_name) { "hutch.integration.exchange.#{SecureRandom.hex(4)}" }
|
|
23
|
+
let(:queue_name) { "hutch.integration.queue.#{SecureRandom.hex(4)}" }
|
|
24
|
+
let(:routing_key) { "hutch.integration.key.#{SecureRandom.hex(4)}" }
|
|
25
|
+
|
|
26
|
+
let(:processed) { [] }
|
|
27
|
+
let(:processed_lock) { Mutex.new }
|
|
28
|
+
let(:timed_out_once) { [false] }
|
|
29
|
+
|
|
30
|
+
let(:server_version) do
|
|
31
|
+
Gem::Version.new(publisher.server_properties['version'].to_s[/\A\d+(\.\d+)*/])
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
let(:blocked_handler_seconds) do
|
|
35
|
+
if server_version >= Gem::Version.new('4.3')
|
|
36
|
+
BLOCKED_HANDLER_SECONDS
|
|
37
|
+
else
|
|
38
|
+
BLOCKED_HANDLER_SECONDS_BEFORE_4_3
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
let(:consumer_class) do
|
|
43
|
+
msgs = processed
|
|
44
|
+
lock = processed_lock
|
|
45
|
+
rk = routing_key
|
|
46
|
+
qn = queue_name
|
|
47
|
+
timed_out = timed_out_once
|
|
48
|
+
blocked = blocked_handler_seconds
|
|
49
|
+
|
|
50
|
+
Class.new do
|
|
51
|
+
include Hutch::Consumer
|
|
52
|
+
|
|
53
|
+
consume rk
|
|
54
|
+
queue_name qn
|
|
55
|
+
arguments(
|
|
56
|
+
'x-queue-type' => 'quorum',
|
|
57
|
+
'x-consumer-timeout' => CONSUMER_TIMEOUT_MS
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
# Both `CONSUMER_TIMEOUT_MS` and this sleep run from the same delivery,
|
|
61
|
+
# so the margin between them does not shrink on a loaded machine.
|
|
62
|
+
define_method(:process) do |message|
|
|
63
|
+
if message['id'] == 'trigger-timeout' && !timed_out[0]
|
|
64
|
+
timed_out[0] = true
|
|
65
|
+
sleep blocked
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
lock.synchronize { msgs << message['id'] }
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
let(:broker) { Hutch::Broker.new }
|
|
74
|
+
let(:worker) { Hutch::Worker.new(broker, [consumer_class], []) }
|
|
75
|
+
|
|
76
|
+
let(:publisher) do
|
|
77
|
+
Bunny.new(
|
|
78
|
+
host: Hutch::Config[:mq_host],
|
|
79
|
+
port: Hutch::Config[:mq_port],
|
|
80
|
+
username: Hutch::Config[:mq_username],
|
|
81
|
+
password: Hutch::Config[:mq_password],
|
|
82
|
+
vhost: Hutch::Config[:mq_vhost]
|
|
83
|
+
).tap(&:start)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
let(:publisher_channel) { publisher.create_channel }
|
|
87
|
+
let(:exchange) { publisher_channel.topic(exchange_name, durable: true) }
|
|
88
|
+
|
|
89
|
+
before do
|
|
90
|
+
Hutch::Logging.logger = logger
|
|
91
|
+
Hutch::Config.set(:mq_exchange, exchange_name)
|
|
92
|
+
Hutch::Config.set(:force_publisher_confirms, false)
|
|
93
|
+
Hutch::Config.set(:client_logger, logger)
|
|
94
|
+
# Channel replacement waits this long for the deliberately blocked
|
|
95
|
+
# handler: the default of 11s would use up most of the consumption window.
|
|
96
|
+
@graceful_exit_timeout = Hutch::Config[:graceful_exit_timeout]
|
|
97
|
+
Hutch::Config.set(:graceful_exit_timeout, 1)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
after do
|
|
101
|
+
publisher_channel.close rescue nil
|
|
102
|
+
publisher.close rescue nil
|
|
103
|
+
broker.disconnect rescue nil
|
|
104
|
+
Hutch::Config.set(:graceful_exit_timeout, @graceful_exit_timeout)
|
|
105
|
+
Hutch::Logging.logger = Logger.new(File::NULL)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def wait_for(timeout, label, &condition)
|
|
109
|
+
await_condition(timeout, label, &condition)
|
|
110
|
+
rescue AwaitHelpers::ConditionTimeout => e
|
|
111
|
+
raise <<~MSG
|
|
112
|
+
#{e.message}
|
|
113
|
+
|
|
114
|
+
processed_messages=#{processed_messages.inspect}
|
|
115
|
+
channel_open=#{broker.channel.open? rescue 'unknown'}
|
|
116
|
+
channel_closed=#{broker.channel.closed? rescue 'unknown'}
|
|
117
|
+
|
|
118
|
+
log output:
|
|
119
|
+
#{log_output}
|
|
120
|
+
MSG
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def processed_messages
|
|
124
|
+
processed_lock.synchronize { processed.dup }
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# `StringIO#string` does not touch the stream position: a rewind here would
|
|
128
|
+
# race with the worker threads that log concurrently and corrupt the buffer.
|
|
129
|
+
def log_output
|
|
130
|
+
log.string
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def publish_message(id)
|
|
134
|
+
exchange.publish(
|
|
135
|
+
JSON.dump('id' => id),
|
|
136
|
+
routing_key: routing_key,
|
|
137
|
+
content_type: 'application/json',
|
|
138
|
+
persistent: true
|
|
139
|
+
)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# RabbitMQ up to 4.2 closes the channel on a delivery acknowledgement
|
|
143
|
+
# timeout; 4.3+ quorum queues instead cancel only the timed out consumer.
|
|
144
|
+
let(:cancels_the_consumer) { server_version >= Gem::Version.new('4.3') }
|
|
145
|
+
|
|
146
|
+
let(:recovery_log_pattern) do
|
|
147
|
+
if cancels_the_consumer
|
|
148
|
+
/cancelled by the server, re-subscribing/i
|
|
149
|
+
else
|
|
150
|
+
/delivery acknowledgement on channel \d+ timed out/i
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Replacing the channel requeues what the cancelled consumer still held, so
|
|
155
|
+
# consumption resumes at once. Reopening one does not, so it resumes at the
|
|
156
|
+
# next consumer timeout tick.
|
|
157
|
+
let(:recovery_seconds) { cancels_the_consumer ? 15 : 90 }
|
|
158
|
+
|
|
159
|
+
# This spec is intentionally slow because RabbitMQ enforces delivery
|
|
160
|
+
# acknowledgement timeouts periodically on a timer, not immediately at the deadline.
|
|
161
|
+
it 're-subscribes and consumes later messages after RabbitMQ times out an unacknowledged delivery' do
|
|
162
|
+
broker.connect
|
|
163
|
+
worker.setup_queues
|
|
164
|
+
|
|
165
|
+
publish_message('trigger-timeout')
|
|
166
|
+
|
|
167
|
+
wait_for(240, 'a delivery acknowledgement timeout to close the channel or cancel the consumer') do
|
|
168
|
+
log_output.match?(recovery_log_pattern)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
publish_message('after-recovery')
|
|
172
|
+
|
|
173
|
+
wait_for(recovery_seconds, 'after-recovery message consumption') do
|
|
174
|
+
processed_messages.include?('after-recovery')
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
expect(log_output).to match(recovery_log_pattern)
|
|
178
|
+
|
|
179
|
+
# A consumed message proves the recovery finished, the publisher rebuild
|
|
180
|
+
# included.
|
|
181
|
+
broker.publish(routing_key, 'id' => 'published-after-recovery')
|
|
182
|
+
|
|
183
|
+
wait_for(15, 'published-after-recovery message consumption') do
|
|
184
|
+
processed_messages.include?('published-after-recovery')
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'hutch/broker'
|
|
3
|
+
require 'hutch/worker'
|
|
4
|
+
require 'hutch/consumer'
|
|
5
|
+
require 'securerandom'
|
|
6
|
+
|
|
7
|
+
describe 'publishing and consuming messages', rabbitmq: true, adapter: :bunny do
|
|
8
|
+
let(:exchange_name) { "hutch.test.#{SecureRandom.hex(4)}" }
|
|
9
|
+
let(:routing_key) { "test.message" }
|
|
10
|
+
let(:received) { [] }
|
|
11
|
+
|
|
12
|
+
let(:consumer_class) do
|
|
13
|
+
msgs = received
|
|
14
|
+
rk = routing_key
|
|
15
|
+
qn = "test_consumer_#{SecureRandom.hex(4)}"
|
|
16
|
+
|
|
17
|
+
Class.new do
|
|
18
|
+
include Hutch::Consumer
|
|
19
|
+
consume rk
|
|
20
|
+
queue_name qn
|
|
21
|
+
|
|
22
|
+
define_method(:process) { |message| msgs << message.body }
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
let(:broker) { Hutch::Broker.new }
|
|
27
|
+
let(:worker) { Hutch::Worker.new(broker, [consumer_class], []) }
|
|
28
|
+
|
|
29
|
+
before do
|
|
30
|
+
Hutch::Config.set(:mq_exchange, exchange_name)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
after do
|
|
34
|
+
broker.disconnect rescue nil
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'publishes and consumes a message' do
|
|
38
|
+
broker.connect
|
|
39
|
+
worker.setup_queues
|
|
40
|
+
|
|
41
|
+
broker.publish(routing_key, { test: 'data' })
|
|
42
|
+
|
|
43
|
+
await_condition(15, 'message consumption') { received.any? }
|
|
44
|
+
|
|
45
|
+
expect(received.first).to eq('test' => 'data')
|
|
46
|
+
end
|
|
47
|
+
end
|
metadata
CHANGED
|
@@ -1,100 +1,71 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hutch
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
platform: java
|
|
6
6
|
authors:
|
|
7
7
|
- Harry Marr
|
|
8
|
-
|
|
8
|
+
- Michael Klishin
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: march_hare
|
|
14
15
|
requirement: !ruby/object:Gem::Requirement
|
|
15
16
|
requirements:
|
|
16
17
|
- - ">="
|
|
17
18
|
- !ruby/object:Gem::Version
|
|
18
|
-
version:
|
|
19
|
-
name: march_hare
|
|
20
|
-
prerelease: false
|
|
19
|
+
version: 4.7.0
|
|
21
20
|
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - ">="
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version:
|
|
26
|
+
version: 4.7.0
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: carrot-top
|
|
28
29
|
requirement: !ruby/object:Gem::Requirement
|
|
29
30
|
requirements:
|
|
30
31
|
- - "~>"
|
|
31
32
|
- !ruby/object:Gem::Version
|
|
32
33
|
version: 0.0.7
|
|
33
|
-
name: carrot-top
|
|
34
|
-
prerelease: false
|
|
35
34
|
type: :runtime
|
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
-
requirements:
|
|
38
|
-
- - "~>"
|
|
39
|
-
- !ruby/object:Gem::Version
|
|
40
|
-
version: 0.0.7
|
|
41
|
-
- !ruby/object:Gem::Dependency
|
|
42
|
-
requirement: !ruby/object:Gem::Requirement
|
|
43
|
-
requirements:
|
|
44
|
-
- - "~>"
|
|
45
|
-
- !ruby/object:Gem::Version
|
|
46
|
-
version: '1.12'
|
|
47
|
-
name: multi_json
|
|
48
35
|
prerelease: false
|
|
49
|
-
type: :runtime
|
|
50
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
37
|
requirements:
|
|
52
38
|
- - "~>"
|
|
53
39
|
- !ruby/object:Gem::Version
|
|
54
|
-
version:
|
|
40
|
+
version: 0.0.7
|
|
55
41
|
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: activesupport
|
|
56
43
|
requirement: !ruby/object:Gem::Requirement
|
|
57
44
|
requirements:
|
|
58
45
|
- - ">="
|
|
59
46
|
- !ruby/object:Gem::Version
|
|
60
47
|
version: '4.2'
|
|
61
|
-
- - "<"
|
|
62
|
-
- !ruby/object:Gem::Version
|
|
63
|
-
version: '6'
|
|
64
|
-
name: activesupport
|
|
65
|
-
prerelease: false
|
|
66
48
|
type: :runtime
|
|
49
|
+
prerelease: false
|
|
67
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
68
51
|
requirements:
|
|
69
52
|
- - ">="
|
|
70
53
|
- !ruby/object:Gem::Version
|
|
71
54
|
version: '4.2'
|
|
72
|
-
- - "<"
|
|
73
|
-
- !ruby/object:Gem::Version
|
|
74
|
-
version: '6'
|
|
75
55
|
description: Hutch is a Ruby library for enabling asynchronous inter-service communication
|
|
76
|
-
using RabbitMQ
|
|
77
|
-
email:
|
|
78
|
-
- developers@gocardless.com
|
|
56
|
+
using RabbitMQ
|
|
79
57
|
executables:
|
|
80
58
|
- hutch
|
|
81
59
|
extensions: []
|
|
82
60
|
extra_rdoc_files: []
|
|
83
61
|
files:
|
|
84
|
-
- ".gitignore"
|
|
85
|
-
- ".rspec"
|
|
86
|
-
- ".travis.yml"
|
|
87
|
-
- ".yardopts"
|
|
88
62
|
- CHANGELOG.md
|
|
89
|
-
- Gemfile
|
|
90
|
-
- Guardfile
|
|
91
63
|
- LICENSE
|
|
92
64
|
- README.md
|
|
93
|
-
-
|
|
65
|
+
- bin/ci/before_build.sh
|
|
66
|
+
- bin/ci/before_build_docker.sh
|
|
67
|
+
- bin/ci/install_on_debian.sh
|
|
94
68
|
- bin/hutch
|
|
95
|
-
- examples/consumer.rb
|
|
96
|
-
- examples/producer.rb
|
|
97
|
-
- hutch.gemspec
|
|
98
69
|
- lib/hutch.rb
|
|
99
70
|
- lib/hutch/acknowledgements/base.rb
|
|
100
71
|
- lib/hutch/acknowledgements/nack_on_all_failures.rb
|
|
@@ -108,9 +79,10 @@ files:
|
|
|
108
79
|
- lib/hutch/error_handlers.rb
|
|
109
80
|
- lib/hutch/error_handlers/airbrake.rb
|
|
110
81
|
- lib/hutch/error_handlers/base.rb
|
|
82
|
+
- lib/hutch/error_handlers/bugsnag.rb
|
|
111
83
|
- lib/hutch/error_handlers/honeybadger.rb
|
|
112
84
|
- lib/hutch/error_handlers/logger.rb
|
|
113
|
-
- lib/hutch/error_handlers/
|
|
85
|
+
- lib/hutch/error_handlers/rollbar.rb
|
|
114
86
|
- lib/hutch/error_handlers/sentry.rb
|
|
115
87
|
- lib/hutch/exceptions.rb
|
|
116
88
|
- lib/hutch/logging.rb
|
|
@@ -119,9 +91,9 @@ files:
|
|
|
119
91
|
- lib/hutch/serializers/identity.rb
|
|
120
92
|
- lib/hutch/serializers/json.rb
|
|
121
93
|
- lib/hutch/tracers.rb
|
|
94
|
+
- lib/hutch/tracers/datadog.rb
|
|
122
95
|
- lib/hutch/tracers/newrelic.rb
|
|
123
96
|
- lib/hutch/tracers/null_tracer.rb
|
|
124
|
-
- lib/hutch/tracers/opbeat.rb
|
|
125
97
|
- lib/hutch/version.rb
|
|
126
98
|
- lib/hutch/waiter.rb
|
|
127
99
|
- lib/hutch/worker.rb
|
|
@@ -132,18 +104,20 @@ files:
|
|
|
132
104
|
- spec/hutch/config_spec.rb
|
|
133
105
|
- spec/hutch/consumer_spec.rb
|
|
134
106
|
- spec/hutch/error_handlers/airbrake_spec.rb
|
|
107
|
+
- spec/hutch/error_handlers/bugsnag_spec.rb
|
|
135
108
|
- spec/hutch/error_handlers/honeybadger_spec.rb
|
|
136
109
|
- spec/hutch/error_handlers/logger_spec.rb
|
|
137
|
-
- spec/hutch/error_handlers/
|
|
110
|
+
- spec/hutch/error_handlers/rollbar_spec.rb
|
|
138
111
|
- spec/hutch/error_handlers/sentry_spec.rb
|
|
139
112
|
- spec/hutch/logger_spec.rb
|
|
140
113
|
- spec/hutch/message_spec.rb
|
|
141
114
|
- spec/hutch/serializers/json_spec.rb
|
|
115
|
+
- spec/hutch/tracers/datadog_spec.rb
|
|
142
116
|
- spec/hutch/waiter_spec.rb
|
|
143
117
|
- spec/hutch/worker_spec.rb
|
|
144
118
|
- spec/hutch_spec.rb
|
|
145
|
-
- spec/
|
|
146
|
-
- spec/
|
|
119
|
+
- spec/integration/channel_recovery_spec.rb
|
|
120
|
+
- spec/integration/publish_consume_spec.rb
|
|
147
121
|
- templates/default/class/html/settings.erb
|
|
148
122
|
- templates/default/class/setup.rb
|
|
149
123
|
- templates/default/fulldoc/html/css/hutch.css
|
|
@@ -153,11 +127,10 @@ files:
|
|
|
153
127
|
- templates/default/method_details/text/settings.erb
|
|
154
128
|
- templates/default/module/html/settings.erb
|
|
155
129
|
- templates/default/module/setup.rb
|
|
156
|
-
homepage: https://github.com/
|
|
130
|
+
homepage: https://github.com/ruby-amqp/hutch
|
|
157
131
|
licenses:
|
|
158
132
|
- MIT
|
|
159
133
|
metadata: {}
|
|
160
|
-
post_install_message:
|
|
161
134
|
rdoc_options: []
|
|
162
135
|
require_paths:
|
|
163
136
|
- lib
|
|
@@ -165,33 +138,33 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
165
138
|
requirements:
|
|
166
139
|
- - ">="
|
|
167
140
|
- !ruby/object:Gem::Version
|
|
168
|
-
version: '
|
|
141
|
+
version: '3.2'
|
|
169
142
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
170
143
|
requirements:
|
|
171
144
|
- - ">="
|
|
172
145
|
- !ruby/object:Gem::Version
|
|
173
146
|
version: '0'
|
|
174
147
|
requirements: []
|
|
175
|
-
|
|
176
|
-
rubygems_version: 2.6.13
|
|
177
|
-
signing_key:
|
|
148
|
+
rubygems_version: 4.0.16
|
|
178
149
|
specification_version: 4
|
|
179
|
-
summary:
|
|
150
|
+
summary: Opinionated asynchronous inter-service communication using RabbitMQ
|
|
180
151
|
test_files:
|
|
181
152
|
- spec/hutch/broker_spec.rb
|
|
182
153
|
- spec/hutch/cli_spec.rb
|
|
183
154
|
- spec/hutch/config_spec.rb
|
|
184
155
|
- spec/hutch/consumer_spec.rb
|
|
185
156
|
- spec/hutch/error_handlers/airbrake_spec.rb
|
|
157
|
+
- spec/hutch/error_handlers/bugsnag_spec.rb
|
|
186
158
|
- spec/hutch/error_handlers/honeybadger_spec.rb
|
|
187
159
|
- spec/hutch/error_handlers/logger_spec.rb
|
|
188
|
-
- spec/hutch/error_handlers/
|
|
160
|
+
- spec/hutch/error_handlers/rollbar_spec.rb
|
|
189
161
|
- spec/hutch/error_handlers/sentry_spec.rb
|
|
190
162
|
- spec/hutch/logger_spec.rb
|
|
191
163
|
- spec/hutch/message_spec.rb
|
|
192
164
|
- spec/hutch/serializers/json_spec.rb
|
|
165
|
+
- spec/hutch/tracers/datadog_spec.rb
|
|
193
166
|
- spec/hutch/waiter_spec.rb
|
|
194
167
|
- spec/hutch/worker_spec.rb
|
|
195
168
|
- spec/hutch_spec.rb
|
|
196
|
-
- spec/
|
|
197
|
-
- spec/
|
|
169
|
+
- spec/integration/channel_recovery_spec.rb
|
|
170
|
+
- spec/integration/publish_consume_spec.rb
|
data/.gitignore
DELETED
data/.rspec
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
--order random
|
data/.travis.yml
DELETED
data/.yardopts
DELETED
data/Gemfile
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
source 'https://rubygems.org'
|
|
2
|
-
|
|
3
|
-
ruby RUBY_VERSION
|
|
4
|
-
|
|
5
|
-
gemspec
|
|
6
|
-
|
|
7
|
-
group :development do
|
|
8
|
-
gem "rake"
|
|
9
|
-
gem "guard", "~> 2.14", platform: :mri_23
|
|
10
|
-
gem "guard-rspec", "~> 4.7", platform: :mri_23
|
|
11
|
-
|
|
12
|
-
gem "yard", "~> 0.9"
|
|
13
|
-
gem 'kramdown', "> 0", platform: :jruby
|
|
14
|
-
gem "redcarpet", "> 0", platform: :mri
|
|
15
|
-
gem "github-markup", "> 0"
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
group :development, :test do
|
|
19
|
-
gem "rspec", "~> 3.5"
|
|
20
|
-
gem "simplecov", "~> 0.12"
|
|
21
|
-
|
|
22
|
-
gem "sentry-raven"
|
|
23
|
-
gem "honeybadger"
|
|
24
|
-
gem "coveralls", "~> 0.8.15", require: false
|
|
25
|
-
gem "newrelic_rpm"
|
|
26
|
-
gem "airbrake", "~> 7.0"
|
|
27
|
-
gem "opbeat", "~> 3.0.9"
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
group :development, :darwin do
|
|
31
|
-
gem "rb-fsevent", "~> 0.9"
|
|
32
|
-
gem "growl", "~> 1.0.3"
|
|
33
|
-
end
|
data/Guardfile
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
guard :rspec, cmd: "bundle exec rspec" do
|
|
2
|
-
require "guard/rspec/dsl"
|
|
3
|
-
dsl = Guard::RSpec::Dsl.new(self)
|
|
4
|
-
|
|
5
|
-
# RSpec files
|
|
6
|
-
rspec = dsl.rspec
|
|
7
|
-
watch(rspec.spec_helper) { rspec.spec_dir }
|
|
8
|
-
watch(rspec.spec_support) { rspec.spec_dir }
|
|
9
|
-
watch(rspec.spec_files)
|
|
10
|
-
|
|
11
|
-
# Ruby files
|
|
12
|
-
ruby = dsl.ruby
|
|
13
|
-
dsl.watch_spec_files_for(ruby.lib_files)
|
|
14
|
-
end
|
data/Rakefile
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
require 'rspec/core/rake_task'
|
|
2
|
-
|
|
3
|
-
desc "Run an IRB session with Hutch pre-loaded"
|
|
4
|
-
task :console do
|
|
5
|
-
exec "irb -I lib -r hutch"
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
desc "Run the test suite"
|
|
9
|
-
RSpec::Core::RakeTask.new(:spec) do |t|
|
|
10
|
-
t.pattern = FileList['spec/**/*_spec.rb']
|
|
11
|
-
t.rspec_opts = %w(--color --format doc)
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
task default: :spec
|
|
15
|
-
|
|
16
|
-
#
|
|
17
|
-
# Re-generate API docs
|
|
18
|
-
#
|
|
19
|
-
require 'yard'
|
|
20
|
-
require 'yard/rake/yardoc_task'
|
|
21
|
-
YARD::Rake::YardocTask.new
|
data/examples/consumer.rb
DELETED
data/examples/producer.rb
DELETED
data/hutch.gemspec
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
require File.expand_path('../lib/hutch/version', __FILE__)
|
|
2
|
-
|
|
3
|
-
Gem::Specification.new do |gem|
|
|
4
|
-
if defined?(JRUBY_VERSION)
|
|
5
|
-
gem.platform = 'java'
|
|
6
|
-
gem.add_runtime_dependency 'march_hare', '>= 3.0.0'
|
|
7
|
-
else
|
|
8
|
-
gem.platform = Gem::Platform::RUBY
|
|
9
|
-
gem.add_runtime_dependency 'bunny', '~> 2.9.0'
|
|
10
|
-
end
|
|
11
|
-
gem.add_runtime_dependency 'carrot-top', '~> 0.0.7'
|
|
12
|
-
gem.add_runtime_dependency 'multi_json', '~> 1.12'
|
|
13
|
-
gem.add_runtime_dependency 'activesupport', '>= 4.2', '< 6'
|
|
14
|
-
|
|
15
|
-
gem.name = 'hutch'
|
|
16
|
-
gem.summary = 'Easy inter-service communication using RabbitMQ.'
|
|
17
|
-
gem.description = 'Hutch is a Ruby library for enabling asynchronous ' \
|
|
18
|
-
'inter-service communication using RabbitMQ.'
|
|
19
|
-
gem.version = Hutch::VERSION.dup
|
|
20
|
-
gem.required_ruby_version = '>= 2.2'
|
|
21
|
-
gem.authors = ['Harry Marr']
|
|
22
|
-
gem.email = ['developers@gocardless.com']
|
|
23
|
-
gem.homepage = 'https://github.com/gocardless/hutch'
|
|
24
|
-
gem.require_paths = ['lib']
|
|
25
|
-
gem.license = 'MIT'
|
|
26
|
-
gem.executables = ['hutch']
|
|
27
|
-
gem.files = `git ls-files`.split("\n")
|
|
28
|
-
gem.test_files = `git ls-files -- spec/*`.split("\n")
|
|
29
|
-
end
|
data/lib/hutch/tracers/opbeat.rb
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
require 'opbeat'
|
|
2
|
-
|
|
3
|
-
module Hutch
|
|
4
|
-
module Tracers
|
|
5
|
-
# Tracer for Opbeat, which traces each message processed.
|
|
6
|
-
class Opbeat
|
|
7
|
-
KIND = 'messaging.hutch'.freeze
|
|
8
|
-
|
|
9
|
-
# @param klass [Consumer] Consumer instance (!)
|
|
10
|
-
def initialize(klass)
|
|
11
|
-
@klass = klass
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
# @param message [Message]
|
|
15
|
-
def handle(message)
|
|
16
|
-
::Opbeat.transaction(sig, KIND, extra: extra_from(message)) do
|
|
17
|
-
@klass.process(message)
|
|
18
|
-
end.done(true)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
private
|
|
22
|
-
|
|
23
|
-
def sig
|
|
24
|
-
@klass.class.name
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def extra_from(message)
|
|
28
|
-
{
|
|
29
|
-
body: message.body.to_s,
|
|
30
|
-
message_id: message.message_id,
|
|
31
|
-
timestamp: message.timestamp,
|
|
32
|
-
routing_key: message.routing_key
|
|
33
|
-
}
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
end
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe Hutch::ErrorHandlers::Opbeat do
|
|
4
|
-
let(:error_handler) { Hutch::ErrorHandlers::Opbeat.new }
|
|
5
|
-
|
|
6
|
-
describe '#handle' do
|
|
7
|
-
let(:properties) { OpenStruct.new(message_id: "1") }
|
|
8
|
-
let(:payload) { "{}" }
|
|
9
|
-
let(:error) do
|
|
10
|
-
begin
|
|
11
|
-
raise "Stuff went wrong"
|
|
12
|
-
rescue RuntimeError => err
|
|
13
|
-
err
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
it "logs the error to Opbeat" do
|
|
18
|
-
expect(Opbeat).to receive(:report).with(error, extra: { payload: payload })
|
|
19
|
-
error_handler.handle(properties, payload, double, error)
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
describe '#handle_setup_exception' do
|
|
24
|
-
let(:error) do
|
|
25
|
-
begin
|
|
26
|
-
raise "Stuff went wrong during setup"
|
|
27
|
-
rescue RuntimeError => err
|
|
28
|
-
err
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
it "logs the error to Opbeat" do
|
|
33
|
-
expect(Opbeat).to receive(:report).with(error)
|
|
34
|
-
error_handler.handle_setup_exception(error)
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
end
|