hutch 0.18.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +3 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +20 -8
  5. data/.yardopts +5 -0
  6. data/CHANGELOG.md +466 -2
  7. data/Gemfile +18 -4
  8. data/Guardfile +13 -4
  9. data/LICENSE +2 -1
  10. data/README.md +397 -32
  11. data/Rakefile +8 -1
  12. data/bin/ci/before_build.sh +20 -0
  13. data/bin/ci/install_on_debian.sh +46 -0
  14. data/hutch.gemspec +6 -7
  15. data/lib/hutch/acknowledgements/base.rb +16 -0
  16. data/lib/hutch/acknowledgements/nack_on_all_failures.rb +19 -0
  17. data/lib/hutch/adapters/march_hare.rb +1 -1
  18. data/lib/hutch/broker.rb +127 -103
  19. data/lib/hutch/cli.rb +66 -25
  20. data/lib/hutch/config.rb +230 -55
  21. data/lib/hutch/consumer.rb +42 -3
  22. data/lib/hutch/error_handlers/airbrake.rb +44 -16
  23. data/lib/hutch/error_handlers/base.rb +15 -0
  24. data/lib/hutch/error_handlers/bugsnag.rb +30 -0
  25. data/lib/hutch/error_handlers/honeybadger.rb +33 -18
  26. data/lib/hutch/error_handlers/logger.rb +12 -6
  27. data/lib/hutch/error_handlers/rollbar.rb +28 -0
  28. data/lib/hutch/error_handlers/sentry.rb +15 -12
  29. data/lib/hutch/error_handlers/sentry_raven.rb +31 -0
  30. data/lib/hutch/error_handlers.rb +3 -0
  31. data/lib/hutch/exceptions.rb +8 -1
  32. data/lib/hutch/logging.rb +5 -5
  33. data/lib/hutch/message.rb +2 -4
  34. data/lib/hutch/publisher.rb +75 -0
  35. data/lib/hutch/serializers/identity.rb +19 -0
  36. data/lib/hutch/serializers/json.rb +22 -0
  37. data/lib/hutch/tracers/datadog.rb +17 -0
  38. data/lib/hutch/tracers.rb +1 -0
  39. data/lib/hutch/version.rb +1 -2
  40. data/lib/hutch/waiter.rb +104 -0
  41. data/lib/hutch/worker.rb +81 -75
  42. data/lib/hutch.rb +15 -6
  43. data/lib/yard-settings/handler.rb +38 -0
  44. data/lib/yard-settings/yard-settings.rb +2 -0
  45. data/spec/hutch/broker_spec.rb +162 -77
  46. data/spec/hutch/cli_spec.rb +16 -3
  47. data/spec/hutch/config_spec.rb +121 -22
  48. data/spec/hutch/consumer_spec.rb +82 -4
  49. data/spec/hutch/error_handlers/airbrake_spec.rb +25 -10
  50. data/spec/hutch/error_handlers/bugsnag_spec.rb +55 -0
  51. data/spec/hutch/error_handlers/honeybadger_spec.rb +24 -2
  52. data/spec/hutch/error_handlers/logger_spec.rb +14 -1
  53. data/spec/hutch/error_handlers/rollbar_spec.rb +45 -0
  54. data/spec/hutch/error_handlers/sentry_raven_spec.rb +37 -0
  55. data/spec/hutch/error_handlers/sentry_spec.rb +21 -2
  56. data/spec/hutch/logger_spec.rb +12 -6
  57. data/spec/hutch/message_spec.rb +2 -2
  58. data/spec/hutch/serializers/json_spec.rb +17 -0
  59. data/spec/hutch/tracers/datadog_spec.rb +44 -0
  60. data/spec/hutch/waiter_spec.rb +51 -0
  61. data/spec/hutch/worker_spec.rb +89 -5
  62. data/spec/spec_helper.rb +7 -5
  63. data/templates/default/class/html/settings.erb +0 -0
  64. data/templates/default/class/setup.rb +4 -0
  65. data/templates/default/fulldoc/html/css/hutch.css +13 -0
  66. data/templates/default/layout/html/setup.rb +7 -0
  67. data/templates/default/method_details/html/settings.erb +5 -0
  68. data/templates/default/method_details/setup.rb +4 -0
  69. data/templates/default/method_details/text/settings.erb +0 -0
  70. data/templates/default/module/html/settings.erb +40 -0
  71. data/templates/default/module/setup.rb +4 -0
  72. metadata +62 -43
  73. data/circle.yml +0 -3
@@ -3,10 +3,23 @@ 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', get_arguments: {}) }
6
+ get_queue_name: 'consumer', get_arguments: {},
7
+ get_serializer: nil) }
7
8
  let(:consumers) { [consumer, double('Consumer')] }
8
9
  let(:broker) { Hutch::Broker.new }
9
- subject(:worker) { Hutch::Worker.new(broker, consumers) }
10
+ let(:setup_procs) { Array.new(2) { Proc.new {} } }
11
+ subject(:worker) { Hutch::Worker.new(broker, consumers, setup_procs) }
12
+
13
+ describe ".#run" do
14
+ it "calls each setup proc" do
15
+ setup_procs.each { |prc| expect(prc).to receive(:call) }
16
+ allow(worker).to receive(:setup_queues)
17
+ allow(Hutch::Waiter).to receive(:wait_until_signaled)
18
+ allow(broker).to receive(:stop)
19
+
20
+ worker.run
21
+ end
22
+ end
10
23
 
11
24
  describe '#setup_queues' do
12
25
  it 'sets up queues for each of the consumers' do
@@ -19,7 +32,6 @@ describe Hutch::Worker do
19
32
 
20
33
  describe '#setup_queue' do
21
34
  let(:queue) { double('Queue', bind: nil, subscribe: nil) }
22
- before { allow(worker).to receive_messages(consumer_queue: queue) }
23
35
  before { allow(broker).to receive_messages(queue: queue, bind_queue: nil) }
24
36
 
25
37
  it 'creates a queue' do
@@ -33,9 +45,27 @@ describe Hutch::Worker do
33
45
  end
34
46
 
35
47
  it 'sets up a subscription' do
36
- expect(queue).to receive(:subscribe).with(manual_ack: true)
48
+ expect(queue).to receive(:subscribe).with(consumer_tag: %r(^hutch\-.{36}$), manual_ack: true)
37
49
  worker.setup_queue(consumer)
38
50
  end
51
+
52
+ context 'with a configured consumer tag prefix' do
53
+ before { Hutch::Config.set(:consumer_tag_prefix, 'appname') }
54
+
55
+ it 'sets up a subscription with the configured tag prefix' do
56
+ expect(queue).to receive(:subscribe).with(consumer_tag: %r(^appname\-.{36}$), manual_ack: true)
57
+ worker.setup_queue(consumer)
58
+ end
59
+ end
60
+
61
+ context 'with a configured consumer tag prefix that is too long' do
62
+ let(:maximum_size) { 255 - SecureRandom.uuid.size - 1 }
63
+ before { Hutch::Config.set(:consumer_tag_prefix, 'a'.*(maximum_size + 1)) }
64
+
65
+ it 'raises an error' do
66
+ expect { worker.setup_queue(consumer) }.to raise_error(/Tag must be 255 bytes long at most/)
67
+ end
68
+ end
39
69
  end
40
70
 
41
71
  describe '#handle_message' do
@@ -43,7 +73,7 @@ describe Hutch::Worker do
43
73
  let(:consumer_instance) { double('Consumer instance') }
44
74
  let(:delivery_info) { double('Delivery Info', routing_key: '',
45
75
  delivery_tag: 'dt') }
46
- let(:properties) { double('Properties', message_id: nil) }
76
+ let(:properties) { double('Properties', message_id: nil, content_type: "application/json") }
47
77
  before { allow(consumer).to receive_messages(new: consumer_instance) }
48
78
  before { allow(broker).to receive(:ack) }
49
79
  before { allow(broker).to receive(:nack) }
@@ -62,6 +92,25 @@ describe Hutch::Worker do
62
92
  worker.handle_message(consumer, delivery_info, properties, payload)
63
93
  end
64
94
 
95
+ context 'when the consumer fails and a requeue is configured' do
96
+
97
+ it 'requeues the message' do
98
+ allow(consumer_instance).to receive(:process).and_raise('failed')
99
+ requeuer = double
100
+ allow(requeuer).to receive(:handle) { |delivery_info, properties, broker, e|
101
+ broker.requeue delivery_info.delivery_tag
102
+ true
103
+ }
104
+ allow(worker).to receive(:error_acknowledgements).and_return([requeuer])
105
+ expect(broker).to_not receive(:ack)
106
+ expect(broker).to_not receive(:nack)
107
+ expect(broker).to receive(:requeue)
108
+
109
+ worker.handle_message(consumer, delivery_info, properties, payload)
110
+ end
111
+ end
112
+
113
+
65
114
  context 'when the consumer raises an exception' do
66
115
  before { allow(consumer_instance).to receive(:process).and_raise('a consumer error') }
67
116
 
@@ -94,5 +143,40 @@ describe Hutch::Worker do
94
143
  end
95
144
  end
96
145
  end
146
+
147
+
148
+ describe '#acknowledge_error' do
149
+ let(:delivery_info) { double('Delivery Info', routing_key: '',
150
+ delivery_tag: 'dt') }
151
+ let(:properties) { double('Properties', message_id: 'abc123') }
152
+
153
+ subject { worker.acknowledge_error delivery_info, properties, broker, StandardError.new }
154
+
155
+ it 'stops when it runs a successful acknowledgement' do
156
+ skip_ack = double handle: false
157
+ always_ack = double handle: true
158
+ never_used = double handle: true
159
+
160
+ allow(worker).
161
+ to receive(:error_acknowledgements).
162
+ and_return([skip_ack, always_ack, never_used])
163
+
164
+ expect(never_used).to_not receive(:handle)
165
+
166
+ subject
167
+ end
168
+
169
+ it 'defaults to nacking' do
170
+ skip_ack = double handle: false
171
+
172
+ allow(worker).
173
+ to receive(:error_acknowledgements).
174
+ and_return([skip_ack, skip_ack])
175
+
176
+ expect(broker).to receive(:nack)
177
+
178
+ subject
179
+ end
180
+ end
97
181
  end
98
182
 
data/spec/spec_helper.rb CHANGED
@@ -13,8 +13,10 @@ require 'raven'
13
13
  require 'hutch'
14
14
  require 'logger'
15
15
 
16
+ # set logger to be a null logger
17
+ Hutch::Logging.logger = Logger.new(File::NULL)
18
+
16
19
  RSpec.configure do |config|
17
- config.before(:all) { Hutch::Config.log_level = Logger::FATAL }
18
20
  config.raise_errors_for_deprecations!
19
21
 
20
22
  if defined?(JRUBY_VERSION)
@@ -22,6 +24,10 @@ RSpec.configure do |config|
22
24
  else
23
25
  config.filter_run_excluding adapter: :march_hare
24
26
  end
27
+
28
+ config.mock_with :rspec do |mocks|
29
+ mocks.verify_partial_doubles = true
30
+ end
25
31
  end
26
32
 
27
33
  # Constants (classes, etc) defined within a block passed to this method
@@ -34,7 +40,3 @@ ensure
34
40
  Object.send(:remove_const, constant)
35
41
  end
36
42
  end
37
-
38
- def deep_copy(obj)
39
- Marshal.load(Marshal.dump(obj))
40
- end
File without changes
@@ -0,0 +1,4 @@
1
+ def init
2
+ super
3
+ sections.push :settings
4
+ end
@@ -0,0 +1,13 @@
1
+ .settings {
2
+ border-spacing: 2.5rem;
3
+ border-collapse: collapse;
4
+ }
5
+
6
+ .settings thead th {
7
+ text-align: left;
8
+ }
9
+
10
+ .settings thead th,
11
+ .settings tbody td {
12
+ padding: .5em 1em;
13
+ }
@@ -0,0 +1,7 @@
1
+ def init
2
+ super
3
+ end
4
+
5
+ def stylesheets
6
+ super + %w(css/hutch.css)
7
+ end
@@ -0,0 +1,5 @@
1
+ <% if object['custom_field'] %>
2
+ <p>
3
+ <%= object['custom_field'] %>
4
+ </p>
5
+ <% end %>
@@ -0,0 +1,4 @@
1
+ def init
2
+ super
3
+ sections.last.place(:settings).after(:source)
4
+ end
@@ -0,0 +1,40 @@
1
+ <% if object['setting_rows'] %>
2
+ <h2>
3
+ Configuration
4
+ </h2>
5
+
6
+ <div class="tags">
7
+ <table border="1" class="settings">
8
+ <thead>
9
+ <tr>
10
+ <th>
11
+ Setting name
12
+ </th>
13
+ <th>
14
+ Default value
15
+ </th>
16
+ <th>
17
+ Type
18
+ </th>
19
+ <th>
20
+ ENV variable
21
+ </th>
22
+ <th>
23
+ Description
24
+ </th>
25
+ </tr>
26
+ </thead>
27
+ <tbody>
28
+ <% for setting in object['setting_rows'] %>
29
+ <tr>
30
+ <td><tt><%= resolve_links "{Hutch::Config##{setting[:name]} #{setting[:name]}}" %></tt></td>
31
+ <td><%= setting[:default_value] %></td>
32
+ <td><%= setting[:type] %></td>
33
+ <td><tt>HUTCH_<%= setting[:name].upcase %></tt></td>
34
+ <td><%= html_markup_markdown setting[:first_line_of_description] %></td>
35
+ </tr>
36
+ <% end %>
37
+ </tbody>
38
+ </table>
39
+ </div>
40
+ <% end %>
@@ -0,0 +1,4 @@
1
+ def init
2
+ super
3
+ sections.place(:settings).before(:children)
4
+ end
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.18.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Harry Marr
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-16 00:00:00.000000000 Z
11
+ date: 2021-07-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bunny
@@ -16,14 +16,20 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 1.7.0
19
+ version: '2.16'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '3.0'
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
27
  - - ">="
25
28
  - !ruby/object:Gem::Version
26
- version: 1.7.0
29
+ version: '2.16'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '3.0'
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: carrot-top
29
35
  requirement: !ruby/object:Gem::Requirement
@@ -44,56 +50,34 @@ dependencies:
44
50
  requirements:
45
51
  - - "~>"
46
52
  - !ruby/object:Gem::Version
47
- version: '1.5'
53
+ version: '1.14'
48
54
  type: :runtime
49
55
  prerelease: false
50
56
  version_requirements: !ruby/object:Gem::Requirement
51
57
  requirements:
52
58
  - - "~>"
53
59
  - !ruby/object:Gem::Version
54
- version: '1.5'
60
+ version: '1.14'
55
61
  - !ruby/object:Gem::Dependency
56
62
  name: activesupport
57
63
  requirement: !ruby/object:Gem::Requirement
58
64
  requirements:
59
65
  - - ">="
60
66
  - !ruby/object:Gem::Version
61
- version: '3.0'
67
+ version: '4.2'
68
+ - - "<"
69
+ - !ruby/object:Gem::Version
70
+ version: '7'
62
71
  type: :runtime
63
72
  prerelease: false
64
73
  version_requirements: !ruby/object:Gem::Requirement
65
74
  requirements:
66
75
  - - ">="
67
76
  - !ruby/object:Gem::Version
68
- version: '3.0'
69
- - !ruby/object:Gem::Dependency
70
- name: rspec
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
77
+ version: '4.2'
78
+ - - "<"
74
79
  - !ruby/object:Gem::Version
75
- version: '3.0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: '3.0'
83
- - !ruby/object:Gem::Dependency
84
- name: simplecov
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: 0.7.1
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "~>"
95
- - !ruby/object:Gem::Version
96
- version: 0.7.1
80
+ version: '7'
97
81
  description: Hutch is a Ruby library for enabling asynchronous inter-service communication
98
82
  using RabbitMQ.
99
83
  email:
@@ -104,19 +88,24 @@ extensions: []
104
88
  extra_rdoc_files: []
105
89
  files:
106
90
  - ".gitignore"
91
+ - ".rspec"
107
92
  - ".travis.yml"
93
+ - ".yardopts"
108
94
  - CHANGELOG.md
109
95
  - Gemfile
110
96
  - Guardfile
111
97
  - LICENSE
112
98
  - README.md
113
99
  - Rakefile
100
+ - bin/ci/before_build.sh
101
+ - bin/ci/install_on_debian.sh
114
102
  - bin/hutch
115
- - circle.yml
116
103
  - examples/consumer.rb
117
104
  - examples/producer.rb
118
105
  - hutch.gemspec
119
106
  - lib/hutch.rb
107
+ - lib/hutch/acknowledgements/base.rb
108
+ - lib/hutch/acknowledgements/nack_on_all_failures.rb
120
109
  - lib/hutch/adapter.rb
121
110
  - lib/hutch/adapters/bunny.rb
122
111
  - lib/hutch/adapters/march_hare.rb
@@ -126,35 +115,61 @@ files:
126
115
  - lib/hutch/consumer.rb
127
116
  - lib/hutch/error_handlers.rb
128
117
  - lib/hutch/error_handlers/airbrake.rb
118
+ - lib/hutch/error_handlers/base.rb
119
+ - lib/hutch/error_handlers/bugsnag.rb
129
120
  - lib/hutch/error_handlers/honeybadger.rb
130
121
  - lib/hutch/error_handlers/logger.rb
122
+ - lib/hutch/error_handlers/rollbar.rb
131
123
  - lib/hutch/error_handlers/sentry.rb
124
+ - lib/hutch/error_handlers/sentry_raven.rb
132
125
  - lib/hutch/exceptions.rb
133
126
  - lib/hutch/logging.rb
134
127
  - lib/hutch/message.rb
128
+ - lib/hutch/publisher.rb
129
+ - lib/hutch/serializers/identity.rb
130
+ - lib/hutch/serializers/json.rb
135
131
  - lib/hutch/tracers.rb
132
+ - lib/hutch/tracers/datadog.rb
136
133
  - lib/hutch/tracers/newrelic.rb
137
134
  - lib/hutch/tracers/null_tracer.rb
138
135
  - lib/hutch/version.rb
136
+ - lib/hutch/waiter.rb
139
137
  - lib/hutch/worker.rb
138
+ - lib/yard-settings/handler.rb
139
+ - lib/yard-settings/yard-settings.rb
140
140
  - spec/hutch/broker_spec.rb
141
141
  - spec/hutch/cli_spec.rb
142
142
  - spec/hutch/config_spec.rb
143
143
  - spec/hutch/consumer_spec.rb
144
144
  - spec/hutch/error_handlers/airbrake_spec.rb
145
+ - spec/hutch/error_handlers/bugsnag_spec.rb
145
146
  - spec/hutch/error_handlers/honeybadger_spec.rb
146
147
  - spec/hutch/error_handlers/logger_spec.rb
148
+ - spec/hutch/error_handlers/rollbar_spec.rb
149
+ - spec/hutch/error_handlers/sentry_raven_spec.rb
147
150
  - spec/hutch/error_handlers/sentry_spec.rb
148
151
  - spec/hutch/logger_spec.rb
149
152
  - spec/hutch/message_spec.rb
153
+ - spec/hutch/serializers/json_spec.rb
154
+ - spec/hutch/tracers/datadog_spec.rb
155
+ - spec/hutch/waiter_spec.rb
150
156
  - spec/hutch/worker_spec.rb
151
157
  - spec/hutch_spec.rb
152
158
  - spec/spec_helper.rb
159
+ - templates/default/class/html/settings.erb
160
+ - templates/default/class/setup.rb
161
+ - templates/default/fulldoc/html/css/hutch.css
162
+ - templates/default/layout/html/setup.rb
163
+ - templates/default/method_details/html/settings.erb
164
+ - templates/default/method_details/setup.rb
165
+ - templates/default/method_details/text/settings.erb
166
+ - templates/default/module/html/settings.erb
167
+ - templates/default/module/setup.rb
153
168
  homepage: https://github.com/gocardless/hutch
154
169
  licenses:
155
170
  - MIT
156
171
  metadata: {}
157
- post_install_message:
172
+ post_install_message:
158
173
  rdoc_options: []
159
174
  require_paths:
160
175
  - lib
@@ -162,16 +177,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
162
177
  requirements:
163
178
  - - ">="
164
179
  - !ruby/object:Gem::Version
165
- version: '0'
180
+ version: '2.2'
166
181
  required_rubygems_version: !ruby/object:Gem::Requirement
167
182
  requirements:
168
183
  - - ">="
169
184
  - !ruby/object:Gem::Version
170
185
  version: '0'
171
186
  requirements: []
172
- rubyforge_project:
173
- rubygems_version: 2.4.8
174
- signing_key:
187
+ rubygems_version: 3.1.4
188
+ signing_key:
175
189
  specification_version: 4
176
190
  summary: Easy inter-service communication using RabbitMQ.
177
191
  test_files:
@@ -180,12 +194,17 @@ test_files:
180
194
  - spec/hutch/config_spec.rb
181
195
  - spec/hutch/consumer_spec.rb
182
196
  - spec/hutch/error_handlers/airbrake_spec.rb
197
+ - spec/hutch/error_handlers/bugsnag_spec.rb
183
198
  - spec/hutch/error_handlers/honeybadger_spec.rb
184
199
  - spec/hutch/error_handlers/logger_spec.rb
200
+ - spec/hutch/error_handlers/rollbar_spec.rb
201
+ - spec/hutch/error_handlers/sentry_raven_spec.rb
185
202
  - spec/hutch/error_handlers/sentry_spec.rb
186
203
  - spec/hutch/logger_spec.rb
187
204
  - spec/hutch/message_spec.rb
205
+ - spec/hutch/serializers/json_spec.rb
206
+ - spec/hutch/tracers/datadog_spec.rb
207
+ - spec/hutch/waiter_spec.rb
188
208
  - spec/hutch/worker_spec.rb
189
209
  - spec/hutch_spec.rb
190
210
  - spec/spec_helper.rb
191
- has_rdoc:
data/circle.yml DELETED
@@ -1,3 +0,0 @@
1
- machine:
2
- services:
3
- - rabbitmq-server