beetle 3.1.0 → 3.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 81efac323bc4a748a3e15d4ca496fa826cc75338b6841d28d22970cd38bf7a4d
4
- data.tar.gz: f34c106da764a475f0396b225482a16083b00b659270d58b7b04c6887b59c6fd
3
+ metadata.gz: cfe005056abcea7bb999f5c1ffbc3300882e6625633034e0cc4ad7e8fc2b4d18
4
+ data.tar.gz: bc6a039a77d190c10878045420ce6fe57bb34d05cd343d71bbc8e9dc6832b74c
5
5
  SHA512:
6
- metadata.gz: 933a4abbd1748fca969f40bd1c2cd304302ce70ec52251c0e1af66b491878644bb6be881686d9899718836f709caeba036bab2a0e0df5f4d9824233af7082dd7
7
- data.tar.gz: 4b215e85dd35302221e1d7366f7fbc271025b032fddc9e9a7cf6fa60f37fd8502bcb22605785969cb9607229e74708df97af7d78f51b659159a98ce53c876ec4
6
+ metadata.gz: 284dc26f2ccdcf11df046f977e083ac35ff0f35d759da350508cdaffecdcf3b56579a06381818f613711b9b5b2c57ff7d044d106562b39530b983e4a4148268e
7
+ data.tar.gz: 962ba73a9f2580748e53e846a36fefcbc1ee9a1054a88a8f60f3de77b3824ac547deaa2c69e94995155400e1aca1ce39cd06779efd6d8910420a99d7b682ec07
data/RELEASE_NOTES.rdoc CHANGED
@@ -1,5 +1,8 @@
1
1
  = Release Notes
2
2
 
3
+ == Version 3.1.1
4
+ * added currently processed message to the handler pre-processing step
5
+
3
6
  == Version 3.1.0
4
7
  * added more debug log statements
5
8
  * added new callbacks on class Beetle::Handler:
data/examples/attempts.rb CHANGED
@@ -15,8 +15,8 @@ Beetle.config.logger.level = Logger::INFO
15
15
 
16
16
  # setup client
17
17
  $client = Beetle::Client.new
18
- $client.config.dead_lettering_enabled = true
19
- $client.config.lazy_queues_enabled = true
18
+ $client.config.dead_lettering_enabled = false
19
+ $client.config.lazy_queues_enabled = false
20
20
  $client.configure(:key => "my.test.message") do
21
21
  message(:test)
22
22
  queue(:test)
@@ -49,7 +49,7 @@ module Beetle
49
49
  end
50
50
 
51
51
  # called before message processing starts
52
- def pre_process
52
+ def pre_process(message)
53
53
  end
54
54
 
55
55
  # called for message processing if no processor was specfied when the handler instance
@@ -257,11 +257,18 @@ module Beetle
257
257
 
258
258
  # process this message and do not allow any exception to escape to the caller
259
259
  def process(handler)
260
- logger.debug "Beetle: processing message #{msg_id}(#{timestamp})"
261
260
  result = nil
261
+ begin
262
+ # pre_process might set up log routing and it might raise
263
+ handler.pre_process(self)
264
+ rescue Exception => @pre_exception
265
+ Beetle::reraise_expectation_errors!
266
+ logger.error "Beetle: preprocessing error #{@pre_exception.class}(#{@pre_exception}) for #{msg_id}"
267
+ end
268
+ logger.debug "Beetle: processing message #{msg_id}(#{timestamp})"
262
269
  begin
263
270
  result = process_internal(handler)
264
- handler.process_exception(@exception) if @exception
271
+ handler.process_exception(@exception || @pre_exception) if (@exception || @pre_exception)
265
272
  handler.process_failure(result) if result.failure?
266
273
  rescue Exception => e
267
274
  Beetle::reraise_expectation_errors!
@@ -278,6 +285,9 @@ module Beetle
278
285
  if @exception
279
286
  ack!
280
287
  RC::DecodingError
288
+ elsif @pre_exception
289
+ ack!
290
+ RC::PreprocessingError
281
291
  elsif expired?
282
292
  logger.warn "Beetle: ignored expired message (#{msg_id})!"
283
293
  ack!
data/lib/beetle/r_c.rb CHANGED
@@ -39,6 +39,7 @@ module Beetle
39
39
  rc :MutexLocked, :reject
40
40
  rc :InternalError, :reject
41
41
  rc :DecodingError, :failure
42
+ rc :PreprocessingError, :failure
42
43
 
43
44
  end
44
45
  end
@@ -175,10 +175,9 @@ module Beetle
175
175
  return
176
176
  end
177
177
  begin
178
- processor = Handler.create(handler, opts)
179
- processor.pre_process
180
178
  message_options = opts.merge(:server => server, :store => @client.deduplication_store)
181
179
  m = Message.new(amqp_queue_name, header, data, message_options)
180
+ processor = Handler.create(handler, opts)
182
181
  result = m.process(processor)
183
182
  if result.reject?
184
183
  if @client.config.dead_lettering_enabled?
@@ -203,7 +202,8 @@ module Beetle
203
202
  logger.debug "Beetle: completed #{msg_id}"
204
203
  begin
205
204
  processor.post_process
206
- rescue Exception
205
+ rescue Exception => e
206
+ logger.error "Beetle: post_process error #{e.class}(#{e}) for #{msg_id}"
207
207
  Beetle::reraise_expectation_errors!
208
208
  end
209
209
  end
@@ -1,3 +1,3 @@
1
1
  module Beetle
2
- VERSION = "3.1.0"
2
+ VERSION = "3.2.0"
3
3
  end
@@ -117,6 +117,7 @@ module Beetle
117
117
  def setup
118
118
  @store = DeduplicationStore.new
119
119
  @store.flushdb
120
+ @null_handler = Handler.create(lambda {|*args|})
120
121
  end
121
122
 
122
123
  test "should be able to extract msg_id from any key" do
@@ -135,7 +136,7 @@ module Beetle
135
136
  assert !message.expired?
136
137
  assert !message.redundant?
137
138
 
138
- message.process(lambda {|*args|})
139
+ message.process(@null_handler)
139
140
 
140
141
  @store.keys(message.msg_id).each do |key|
141
142
  assert !@store.redis.exists(key)
@@ -150,8 +151,8 @@ module Beetle
150
151
  assert !message.expired?
151
152
  assert message.redundant?
152
153
 
153
- message.process(lambda {|*args|})
154
- message.process(lambda {|*args|})
154
+ message.process(@null_handler)
155
+ message.process(@null_handler)
155
156
 
156
157
  @store.keys(message.msg_id).each do |key|
157
158
  assert !@store.redis.exists(key)
@@ -166,7 +167,7 @@ module Beetle
166
167
  assert !message.expired?
167
168
  assert message.redundant?
168
169
 
169
- message.process(lambda {|*args|})
170
+ message.process(@null_handler)
170
171
 
171
172
  assert @store.exists(message.msg_id, :status)
172
173
  assert @store.exists(message.msg_id, :expires)
@@ -183,6 +184,7 @@ module Beetle
183
184
  def setup
184
185
  @store = DeduplicationStore.new
185
186
  @store.flushdb
187
+ @null_handler = Handler.create(lambda {|*args|})
186
188
  end
187
189
 
188
190
  test "an expired message should be acked without calling the handler" do
@@ -192,7 +194,7 @@ module Beetle
192
194
  assert message.expired?
193
195
 
194
196
  processed = :no
195
- message.process(lambda {|*args| processed = true})
197
+ message.process(Handler.create(lambda {|*args| processed = true}))
196
198
  assert_equal :no, processed
197
199
  end
198
200
 
@@ -205,7 +207,7 @@ module Beetle
205
207
  assert message.delayed?
206
208
 
207
209
  processed = :no
208
- message.process(lambda {|*args| processed = true})
210
+ message.process(Handler.create(lambda {|*args| processed = true}))
209
211
  assert_equal :no, processed
210
212
  end
211
213
 
@@ -214,7 +216,7 @@ module Beetle
214
216
  header.expects(:ack)
215
217
  message = Message.new("somequeue", header, 'foo', :store => @store)
216
218
 
217
- message.process(lambda {|*args|})
219
+ message.process(@null_handler)
218
220
  assert !message.redundant?
219
221
  assert !@store.exists(message.msg_id, :ack_count)
220
222
  end
@@ -225,7 +227,7 @@ module Beetle
225
227
 
226
228
  message.expects(:ack!)
227
229
  assert message.redundant?
228
- message.process(lambda {|*args|})
230
+ message.process(@null_handler)
229
231
  end
230
232
 
231
233
  test "acking a redundant message should increment the ack_count key" do
@@ -234,7 +236,7 @@ module Beetle
234
236
  message = Message.new("somequeue", header, 'foo', :store => @store)
235
237
 
236
238
  assert_nil @store.get(message.msg_id, :ack_count)
237
- message.process(lambda {|*args|})
239
+ message.process(@null_handler)
238
240
  assert message.redundant?
239
241
  assert_equal "1", @store.get(message.msg_id, :ack_count)
240
242
  end
@@ -244,8 +246,8 @@ module Beetle
244
246
  header.expects(:ack).twice
245
247
  message = Message.new("somequeue", header, 'foo', :store => @store)
246
248
 
247
- message.process(lambda {|*args|})
248
- message.process(lambda {|*args|})
249
+ message.process(@null_handler)
250
+ message.process(@null_handler)
249
251
  assert message.redundant?
250
252
  assert !@store.exists(message.msg_id, :ack_count)
251
253
  end
@@ -263,11 +265,12 @@ module Beetle
263
265
  message = Message.new("somequeue", header, 'foo', :attempts => 2, :store => @store)
264
266
  assert !message.attempts_limit_reached?
265
267
 
266
- proc = mock("proc")
268
+ handler = mock("handler")
267
269
  s = sequence("s")
268
- proc.expects(:call).in_sequence(s)
270
+ handler.expects(:pre_process).with(message).in_sequence(s)
271
+ handler.expects(:call).in_sequence(s)
269
272
  header.expects(:ack).in_sequence(s)
270
- assert_equal RC::OK, message.process(proc)
273
+ assert_equal RC::OK, message.process(handler)
271
274
  end
272
275
 
273
276
  test "after processing a redundant fresh message successfully the ack count should be 1 and the status should be completed" do
@@ -298,25 +301,27 @@ module Beetle
298
301
  header = header_with_params({})
299
302
  message = Message.new("somequeue", header, 'foo', :attempts => 1, :store => @store)
300
303
 
301
- proc = mock("proc")
304
+ handler = mock("handler")
302
305
  s = sequence("s")
306
+ handler.expects(:pre_process).with(message).in_sequence(s)
303
307
  header.expects(:ack).in_sequence(s)
304
- proc.expects(:call).in_sequence(s)
305
- assert_equal RC::OK, message.process(proc)
308
+ handler.expects(:call).in_sequence(s)
309
+ assert_equal RC::OK, message.process(handler)
306
310
  end
307
311
 
308
312
  test "when processing a simple message, RC::AttemptsLimitReached should be returned if the handler crashes" do
309
313
  header = header_with_params({})
310
314
  message = Message.new("somequeue", header, 'foo', :attempts => 1, :store => @store)
311
315
 
312
- proc = mock("proc")
316
+ handler = mock("handler")
313
317
  s = sequence("s")
318
+ handler.expects(:pre_process).with(message).in_sequence(s)
314
319
  header.expects(:ack).in_sequence(s)
315
320
  e = Exception.new("ohoh")
316
- proc.expects(:call).in_sequence(s).raises(e)
317
- proc.expects(:process_exception).with(e).in_sequence(s)
318
- proc.expects(:process_failure).with(RC::AttemptsLimitReached).in_sequence(s)
319
- assert_equal RC::AttemptsLimitReached, message.process(proc)
321
+ handler.expects(:call).in_sequence(s).raises(e)
322
+ handler.expects(:process_exception).with(e).in_sequence(s)
323
+ handler.expects(:process_failure).with(RC::AttemptsLimitReached).in_sequence(s)
324
+ assert_equal RC::AttemptsLimitReached, message.process(handler)
320
325
  end
321
326
 
322
327
  end
@@ -422,7 +427,6 @@ module Beetle
422
427
  assert !message.timed_out?
423
428
 
424
429
  proc = lambda {|*args| raise "crash"}
425
- s = sequence("s")
426
430
  message.expects(:completed!).once
427
431
  header.expects(:ack)
428
432
  assert_equal RC::AttemptsLimitReached, message.__send__(:process_internal, proc)
@@ -436,7 +440,7 @@ module Beetle
436
440
  @store.flushdb
437
441
  end
438
442
 
439
- test "a message with an exception set should not be processed at all, but it should be acked" do
443
+ test "a message with a decoding error should not be processed at all, but it should be acked" do
440
444
  header = {}
441
445
  message = Message.new("somequeue", header, 'foo')
442
446
  assert message.exception
@@ -447,6 +451,17 @@ module Beetle
447
451
  assert_equal RC::DecodingError, message.__send__(:process_internal, proc)
448
452
  end
449
453
 
454
+ test "a message with a preprocessing error set should not be processed at all, but it should be acked" do
455
+ header = header_with_params({})
456
+ message = Message.new("somequeue", header, 'foo')
457
+ message.instance_eval { @pre_exception = StandardError.new("shoo") }
458
+
459
+ proc = mock("proc")
460
+ proc.expects(:call).never
461
+ message.expects(:ack!)
462
+ assert_equal RC::PreprocessingError, message.__send__(:process_internal, proc)
463
+ end
464
+
450
465
  test "a completed existing message should be just acked and not run the handler" do
451
466
  header = header_with_params({})
452
467
  message = Message.new("somequeue", header, 'foo', :attempts => 2, :store => @store)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: beetle
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0
4
+ version: 3.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefan Kaes
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2019-07-05 00:00:00.000000000 Z
15
+ date: 2019-07-09 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: bunny