pebbles-river 0.0.5 → 0.0.6
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.
- data/lib/pebbles/river/version.rb +1 -1
- data/lib/pebbles/river/worker.rb +19 -13
- data/spec/lib/worker_spec.rb +74 -37
- metadata +35 -18
- checksums.yaml +0 -7
data/lib/pebbles/river/worker.rb
CHANGED
@@ -17,10 +17,10 @@ module Pebbles
|
|
17
17
|
# Initializes worker with a handler. Options:
|
18
18
|
#
|
19
19
|
# * `queue`: Same queue options as `River#queue`.
|
20
|
-
# * `on_exception`: If provided, called
|
21
|
-
# due to an exception.
|
22
|
-
#
|
23
|
-
#
|
20
|
+
# * `on_exception`: If provided, called with `exception` as an argument
|
21
|
+
# when a message could not be handled due to an exception. (Connection
|
22
|
+
# errors are not reported, however.)
|
23
|
+
# * `logger`: Optional logger. Defaults to stderr. Pass nil to disable.
|
24
24
|
# * `managed_acking`: If true, ack/nack handling is automatic; every message
|
25
25
|
# is automatically acked unless the handler returns false or the handler
|
26
26
|
# raises an exception, in which case it's nacked. If false, the handler
|
@@ -34,8 +34,8 @@ module Pebbles
|
|
34
34
|
def initialize(handler, options = {})
|
35
35
|
options.assert_valid_keys(
|
36
36
|
:queue,
|
37
|
+
:logger,
|
37
38
|
:on_exception,
|
38
|
-
:on_connection_error,
|
39
39
|
:managed_acking)
|
40
40
|
|
41
41
|
unless handler.respond_to?(:call)
|
@@ -44,12 +44,12 @@ module Pebbles
|
|
44
44
|
|
45
45
|
@queue_options = (options[:queue] || {}).freeze
|
46
46
|
@managed_acking = !!options.fetch(:managed_acking, true)
|
47
|
-
@on_exception = options[:on_exception] || ->(
|
48
|
-
@on_connection_error = options[:on_connection_error] || @on_exception
|
47
|
+
@on_exception = options[:on_exception] || ->(*args) { }
|
49
48
|
@handler = handler
|
50
49
|
@river = River.new
|
51
50
|
@next_event_time = Time.now
|
52
51
|
@rate_limiter = RateLimiter.new(1.0, 10)
|
52
|
+
@logger = options.fetch(:logger, Logger.new($stderr))
|
53
53
|
end
|
54
54
|
|
55
55
|
# Runs the handler once.
|
@@ -163,6 +163,10 @@ module Pebbles
|
|
163
163
|
begin
|
164
164
|
yield
|
165
165
|
rescue *CONNECTION_EXCEPTIONS => exception
|
166
|
+
if @logger
|
167
|
+
@logger.error("Connection error (#{exception.class}): #{exception}")
|
168
|
+
end
|
169
|
+
|
166
170
|
@rate_limiter.increment
|
167
171
|
|
168
172
|
if @queue
|
@@ -173,11 +177,11 @@ module Pebbles
|
|
173
177
|
end
|
174
178
|
|
175
179
|
@river.disconnect
|
176
|
-
|
177
|
-
ignore_exceptions do
|
178
|
-
@on_connection_error.call(exception)
|
179
|
-
end
|
180
180
|
rescue => exception
|
181
|
+
if @logger
|
182
|
+
@logger.error("Exception (#{exception.class}) while handling message: #{exception}")
|
183
|
+
end
|
184
|
+
|
181
185
|
@rate_limiter.increment
|
182
186
|
|
183
187
|
ignore_exceptions do
|
@@ -188,8 +192,10 @@ module Pebbles
|
|
188
192
|
|
189
193
|
def ignore_exceptions(&block)
|
190
194
|
yield
|
191
|
-
rescue
|
192
|
-
|
195
|
+
rescue => e
|
196
|
+
if @logger
|
197
|
+
@logger.warn("Ignoring exception (#{e.class}): #{e}")
|
198
|
+
end
|
193
199
|
end
|
194
200
|
|
195
201
|
CONNECTION_EXCEPTIONS = [
|
data/spec/lib/worker_spec.rb
CHANGED
@@ -187,54 +187,91 @@ describe Worker do
|
|
187
187
|
Bunny::ProtocolError,
|
188
188
|
Errno::ECONNRESET
|
189
189
|
].each do |exception_class|
|
190
|
-
|
191
|
-
|
190
|
+
context "connection exception #{exception_class}" do
|
191
|
+
let :exception do
|
192
|
+
exception_class.new("Dangit")
|
193
|
+
end
|
192
194
|
|
193
|
-
handler
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
195
|
+
let :handler do
|
196
|
+
handler = double('handler')
|
197
|
+
handler.stub(:call).and_return {
|
198
|
+
raise exception
|
199
|
+
}
|
200
|
+
handler
|
201
|
+
end
|
198
202
|
|
199
|
-
|
200
|
-
|
201
|
-
expect(river).to receive(:queue).with({name: 'foo'})
|
202
|
-
expect(river).to receive(:disconnect).at_least(1).times
|
203
|
+
it "performs connection reset on #{exception_class}" do
|
204
|
+
expect(queue).to receive(:close).at_least(1).times
|
203
205
|
|
204
|
-
|
205
|
-
end
|
206
|
-
end
|
206
|
+
expect(handler).to receive(:call).with(message)
|
207
207
|
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
208
|
+
expect(river).to receive(:connected?).with(no_args).at_least(1).times
|
209
|
+
expect(river).to_not receive(:connect)
|
210
|
+
expect(river).to receive(:queue).with({name: 'foo'})
|
211
|
+
expect(river).to receive(:disconnect).at_least(1).times
|
212
212
|
|
213
|
-
|
213
|
+
subject.new(handler, queue: {name: 'foo'}).run_once
|
214
|
+
end
|
214
215
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
erroring_handler.stub(:on_connection_error).and_return(nil)
|
220
|
-
expect(erroring_handler).to receive(:call).with(message)
|
216
|
+
it "does not call #on_exception on connection error" do
|
217
|
+
on_exception_callback = double('on_connection_error')
|
218
|
+
on_exception_callback.stub(:call) { }
|
219
|
+
expect(on_exception_callback).to_not receive(:call)
|
221
220
|
|
222
|
-
|
223
|
-
|
224
|
-
|
221
|
+
expect(queue).to receive(:close).at_least(1).times
|
222
|
+
|
223
|
+
expect(handler).to receive(:call).at_least(1).times
|
224
|
+
|
225
|
+
expect(river).to receive(:connected?).with(no_args).at_least(1).times
|
226
|
+
expect(river).to_not receive(:connect)
|
227
|
+
expect(river).to receive(:disconnect).at_least(1).times
|
228
|
+
|
229
|
+
subject.new(handler,
|
230
|
+
queue: {name: 'foo'},
|
231
|
+
on_exception: on_exception_callback).run_once
|
232
|
+
end
|
233
|
+
|
234
|
+
it "logs error to logger" do
|
235
|
+
expect(handler).to receive(:call).with(message)
|
236
|
+
|
237
|
+
logger = double('logger')
|
238
|
+
logger.stub(:error) { }
|
239
|
+
expect(logger).to receive(:error).
|
240
|
+
with(/#{Regexp.escape(exception.message)}/).at_least(1).times
|
225
241
|
|
226
|
-
|
227
|
-
|
228
|
-
|
242
|
+
river.stub(:disconnect)
|
243
|
+
|
244
|
+
subject.new(handler,
|
245
|
+
queue: {name: 'foo'},
|
246
|
+
logger: logger).run_once
|
247
|
+
end
|
248
|
+
end
|
229
249
|
end
|
230
250
|
|
231
|
-
|
232
|
-
|
233
|
-
|
251
|
+
context 'non-connection exception' do
|
252
|
+
it "calls #on_exception" do
|
253
|
+
expect(queue).to_not receive(:close)
|
254
|
+
expect(on_exception_callback).to receive(:call).with(io_error)
|
255
|
+
|
256
|
+
subject.new(io_error_raising_handler,
|
257
|
+
queue: {name: 'foo'},
|
258
|
+
on_exception: on_exception_callback).run_once
|
259
|
+
end
|
234
260
|
|
235
|
-
|
236
|
-
|
237
|
-
|
261
|
+
it "logs error to logger" do
|
262
|
+
on_exception_callback.stub(:call)
|
263
|
+
|
264
|
+
river.stub(:disconnect)
|
265
|
+
|
266
|
+
logger = double('logger')
|
267
|
+
logger.stub(:error) { }
|
268
|
+
expect(logger).to receive(:error).
|
269
|
+
with(/#{Regexp.escape(io_error.message)}/).at_least(1).times
|
270
|
+
|
271
|
+
subject.new(io_error_raising_handler,
|
272
|
+
queue: {name: 'foo'},
|
273
|
+
logger: logger).run_once
|
274
|
+
end
|
238
275
|
end
|
239
276
|
|
240
277
|
end
|
metadata
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pebbles-river
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Alexander Staubo
|
@@ -9,25 +10,28 @@ authors:
|
|
9
10
|
autorequire:
|
10
11
|
bindir: bin
|
11
12
|
cert_chain: []
|
12
|
-
date: 2014-05-
|
13
|
+
date: 2014-05-29 00:00:00.000000000 Z
|
13
14
|
dependencies:
|
14
15
|
- !ruby/object:Gem::Dependency
|
15
16
|
name: pebblebed
|
16
17
|
requirement: !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
17
19
|
requirements:
|
18
|
-
- - '>='
|
20
|
+
- - ! '>='
|
19
21
|
- !ruby/object:Gem::Version
|
20
22
|
version: 0.1.3
|
21
23
|
type: :runtime
|
22
24
|
prerelease: false
|
23
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
24
27
|
requirements:
|
25
|
-
- - '>='
|
28
|
+
- - ! '>='
|
26
29
|
- !ruby/object:Gem::Version
|
27
30
|
version: 0.1.3
|
28
31
|
- !ruby/object:Gem::Dependency
|
29
32
|
name: bunny
|
30
33
|
requirement: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
31
35
|
requirements:
|
32
36
|
- - ~>
|
33
37
|
- !ruby/object:Gem::Version
|
@@ -35,6 +39,7 @@ dependencies:
|
|
35
39
|
type: :runtime
|
36
40
|
prerelease: false
|
37
41
|
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
38
43
|
requirements:
|
39
44
|
- - ~>
|
40
45
|
- !ruby/object:Gem::Version
|
@@ -42,20 +47,23 @@ dependencies:
|
|
42
47
|
- !ruby/object:Gem::Dependency
|
43
48
|
name: activesupport
|
44
49
|
requirement: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
45
51
|
requirements:
|
46
|
-
- - '>='
|
52
|
+
- - ! '>='
|
47
53
|
- !ruby/object:Gem::Version
|
48
54
|
version: '3.0'
|
49
55
|
type: :runtime
|
50
56
|
prerelease: false
|
51
57
|
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
52
59
|
requirements:
|
53
|
-
- - '>='
|
60
|
+
- - ! '>='
|
54
61
|
- !ruby/object:Gem::Version
|
55
62
|
version: '3.0'
|
56
63
|
- !ruby/object:Gem::Dependency
|
57
64
|
name: servolux
|
58
65
|
requirement: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
59
67
|
requirements:
|
60
68
|
- - ~>
|
61
69
|
- !ruby/object:Gem::Version
|
@@ -63,6 +71,7 @@ dependencies:
|
|
63
71
|
type: :runtime
|
64
72
|
prerelease: false
|
65
73
|
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
66
75
|
requirements:
|
67
76
|
- - ~>
|
68
77
|
- !ruby/object:Gem::Version
|
@@ -70,20 +79,23 @@ dependencies:
|
|
70
79
|
- !ruby/object:Gem::Dependency
|
71
80
|
name: rspec
|
72
81
|
requirement: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
73
83
|
requirements:
|
74
|
-
- - '>='
|
84
|
+
- - ! '>='
|
75
85
|
- !ruby/object:Gem::Version
|
76
86
|
version: '0'
|
77
87
|
type: :development
|
78
88
|
prerelease: false
|
79
89
|
version_requirements: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
80
91
|
requirements:
|
81
|
-
- - '>='
|
92
|
+
- - ! '>='
|
82
93
|
- !ruby/object:Gem::Version
|
83
94
|
version: '0'
|
84
95
|
- !ruby/object:Gem::Dependency
|
85
96
|
name: bundler
|
86
97
|
requirement: !ruby/object:Gem::Requirement
|
98
|
+
none: false
|
87
99
|
requirements:
|
88
100
|
- - ~>
|
89
101
|
- !ruby/object:Gem::Version
|
@@ -91,6 +103,7 @@ dependencies:
|
|
91
103
|
type: :development
|
92
104
|
prerelease: false
|
93
105
|
version_requirements: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
94
107
|
requirements:
|
95
108
|
- - ~>
|
96
109
|
- !ruby/object:Gem::Version
|
@@ -98,29 +111,33 @@ dependencies:
|
|
98
111
|
- !ruby/object:Gem::Dependency
|
99
112
|
name: rake
|
100
113
|
requirement: !ruby/object:Gem::Requirement
|
114
|
+
none: false
|
101
115
|
requirements:
|
102
|
-
- - '>='
|
116
|
+
- - ! '>='
|
103
117
|
- !ruby/object:Gem::Version
|
104
118
|
version: '0'
|
105
119
|
type: :development
|
106
120
|
prerelease: false
|
107
121
|
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
none: false
|
108
123
|
requirements:
|
109
|
-
- - '>='
|
124
|
+
- - ! '>='
|
110
125
|
- !ruby/object:Gem::Version
|
111
126
|
version: '0'
|
112
127
|
- !ruby/object:Gem::Dependency
|
113
128
|
name: simplecov
|
114
129
|
requirement: !ruby/object:Gem::Requirement
|
130
|
+
none: false
|
115
131
|
requirements:
|
116
|
-
- - '>='
|
132
|
+
- - ! '>='
|
117
133
|
- !ruby/object:Gem::Version
|
118
134
|
version: '0'
|
119
135
|
type: :development
|
120
136
|
prerelease: false
|
121
137
|
version_requirements: !ruby/object:Gem::Requirement
|
138
|
+
none: false
|
122
139
|
requirements:
|
123
|
-
- - '>='
|
140
|
+
- - ! '>='
|
124
141
|
- !ruby/object:Gem::Version
|
125
142
|
version: '0'
|
126
143
|
description: Implements an event river mechanism for Pebblebed.
|
@@ -155,26 +172,27 @@ files:
|
|
155
172
|
homepage: ''
|
156
173
|
licenses:
|
157
174
|
- MIT
|
158
|
-
metadata: {}
|
159
175
|
post_install_message:
|
160
176
|
rdoc_options: []
|
161
177
|
require_paths:
|
162
178
|
- lib
|
163
179
|
required_ruby_version: !ruby/object:Gem::Requirement
|
180
|
+
none: false
|
164
181
|
requirements:
|
165
|
-
- - '>='
|
182
|
+
- - ! '>='
|
166
183
|
- !ruby/object:Gem::Version
|
167
184
|
version: '0'
|
168
185
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
186
|
+
none: false
|
169
187
|
requirements:
|
170
|
-
- - '>='
|
188
|
+
- - ! '>='
|
171
189
|
- !ruby/object:Gem::Version
|
172
190
|
version: '0'
|
173
191
|
requirements: []
|
174
192
|
rubyforge_project:
|
175
|
-
rubygems_version:
|
193
|
+
rubygems_version: 1.8.23.2
|
176
194
|
signing_key:
|
177
|
-
specification_version:
|
195
|
+
specification_version: 3
|
178
196
|
summary: Implements an event river mechanism for Pebblebed.
|
179
197
|
test_files:
|
180
198
|
- spec/lib/river_spec.rb
|
@@ -182,4 +200,3 @@ test_files:
|
|
182
200
|
- spec/lib/subscription_spec.rb
|
183
201
|
- spec/lib/worker_spec.rb
|
184
202
|
- spec/spec_helper.rb
|
185
|
-
has_rdoc:
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: 3a9d7fc14df9e1ff6e3ba421d3821b30e1bf44f6
|
4
|
-
data.tar.gz: 22387fcc520f21ca016f4b2ddff442202b94d5e0
|
5
|
-
SHA512:
|
6
|
-
metadata.gz: 029b4e3683dcbed2cdebda4744199527a59c64513f22404d510f5a552788a708d159d4495d248e2d1b38c0d7c52bf2ed3e34b23fcb5c805cb846ee36a9318f0c
|
7
|
-
data.tar.gz: 6d5b93d2ed155f25c3220fd1c992d50c8c0425dd99785706c9a25f7ca728e0fb431df860ddf3557d5fa7e602ea36b2dfd93fcc7327aefd4c950e9c49c3d5346d
|