beetle 2.0.2 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fc653de6c1ae3114292d7a8b6007b45f6f9cf738
4
- data.tar.gz: 6483f18188fe2440c191fd87f42238df3a735d59
3
+ metadata.gz: 7f35943d8dbccaf27c203a95f97bd0c07eac095e
4
+ data.tar.gz: 457e47a4c51befed13d5c79a9b9d30a7e34f565b
5
5
  SHA512:
6
- metadata.gz: c9820af31098f5b6eccab38d3b5d463fb3a3a038ebd6def62a6799fa122deff721dd079bb3faec0f5d35465d0a5c3e293348c90491b99b47e17618c6f7f5b801
7
- data.tar.gz: 0bb4d6042f238635edc3b805dc9819e2bc88d13d2c820eff9bc4f42aa71232aed829814c8d033a38981583e7e4559b81f23027a6160014546b05cefb84647668
6
+ metadata.gz: 3bd412cffe960ec193ce073fcefece2e7656ed4b136246ea4edf46ea57b45245736b6a00266a2f5edf8413f132790a74b6c86dfcf8c6f613b1a289cd6e284bc5
7
+ data.tar.gz: a88e2fbe08e0c0a2730b524e58c2a56a9f711b2bfd449bc9b9c895219a69b5f8af82a9d8715550bbe144a026e16ea45c7b569055517f8208dd2322f66c4951c5
@@ -1,5 +1,9 @@
1
1
  = Release Notes
2
2
 
3
+ == Version 2.1.0
4
+
5
+ * Support exponential backoff when delaying messages using 'max_delay: int' option.
6
+
3
7
  == Version 2.0.1
4
8
 
5
9
  * fixed incorrect computation of responsiveness threshold in
@@ -0,0 +1,72 @@
1
+ # attempts_with_dead_letter_and_exponential_backoff.rb
2
+ # ! check the examples/README.rdoc for information on starting your redis/rabbit !
3
+ #
4
+ # start it with ruby attempts_with_dead_letter_and_exponential_backoff.rb
5
+
6
+ require "rubygems"
7
+ require File.expand_path("../lib/beetle", File.dirname(__FILE__))
8
+
9
+ # set Beetle log level to info, less noisy than debug
10
+ Beetle.config.logger.level = Logger::INFO
11
+
12
+ # setup client with dead lettering enabled
13
+ config = Beetle::Configuration.new
14
+ config.dead_lettering_enabled = true
15
+ config.dead_lettering_msg_ttl = 1000 # millis
16
+ client = Beetle::Client.new(config)
17
+ client.register_queue(:test)
18
+ client.register_message(:test)
19
+
20
+ # purge the test queue
21
+ client.purge(:test)
22
+
23
+ # empty the dedup store
24
+ client.deduplication_store.flushdb
25
+
26
+ # setup our counter
27
+ $completed = 0
28
+ $exceptions_limit = 4
29
+
30
+ # store the start time
31
+ $start_time = Time.now.to_f
32
+
33
+ # declare a handler class for message processing
34
+ # handler fails on the first execution attempt, then succeeds
35
+ class Handler < Beetle::Handler
36
+ # called when the handler receives the message, fails on first two attempts
37
+ # succeeds on the next and counts up our counter
38
+ def process
39
+ logger.info "Attempts: #{message.attempts}, Base Delay: #{message.delay}, Processed at: #{Time.now.to_f - $start_time}"
40
+ raise "attempt #{message.attempts} for message #{message.data}" if message.attempts < $exceptions_limit
41
+ logger.info "processing of message #{message.data} succeeded on attempt #{message.attempts}. completed: #{$completed += 1}"
42
+ end
43
+
44
+ # called when handler process raised an exception
45
+ def error(exception)
46
+ logger.info "execution failed: #{exception}"
47
+ end
48
+ end
49
+
50
+ # register our handler to the message, configure it to our max_attempts limit, we configure a (base) delay of 0.5
51
+ client.register_handler(:test, Handler, exceptions: $exceptions_limit, delay: 1, max_delay: 10)
52
+ # publish test messages
53
+ client.publish(:test, 1) # publish returns the number of servers the message has been sent to
54
+ puts "published 1 test message"
55
+
56
+ # start the listening loop
57
+ client.listen do
58
+ # catch INT-signal and stop listening
59
+ trap("INT") { client.stop_listening }
60
+ # we're adding a periodic timer to check whether all 10 messages have been processed without exceptions
61
+ timer = EM.add_periodic_timer(1) do
62
+ if $completed == 1
63
+ timer.cancel
64
+ client.stop_listening
65
+ end
66
+ end
67
+ end
68
+
69
+ puts "Handled #{$completed} messages"
70
+ if $completed != 1
71
+ raise "Did not handle the correct number of messages"
72
+ end
@@ -0,0 +1,72 @@
1
+ # attempts_with_exponential_backoff.rb
2
+ # ! check the examples/README.rdoc for information on starting your redis/rabbit !
3
+ #
4
+ # start it with ruby attempts_with_exponential_backoff.rb
5
+
6
+ require "rubygems"
7
+ require File.expand_path("../lib/beetle", File.dirname(__FILE__))
8
+
9
+ # set Beetle log level to info, less noisy than debug
10
+ Beetle.config.logger.level = Logger::INFO
11
+
12
+ # setup client
13
+ client = Beetle::Client.new
14
+ client.register_queue(:test)
15
+ client.register_message(:test)
16
+
17
+ # purge the test queue
18
+ client.purge(:test)
19
+
20
+ # empty the dedup store
21
+ client.deduplication_store.flushdb
22
+
23
+ # setup our counter
24
+ $completed = 0
25
+ $exceptions_limit = 4
26
+
27
+ # store the start time
28
+ $start_time = Time.now.to_f
29
+
30
+ # declare a handler class for message processing
31
+ # handler fails on the first $exceptions_limit-1 execution attempts, then succeeds
32
+ class Handler < Beetle::Handler
33
+
34
+ # called when the handler receives the message
35
+ # succeeds on the next and counts up our counter
36
+ def process
37
+ logger.info "Attempts: #{message.attempts}, Base Delay: #{message.delay}, Processed at: #{Time.now.to_f - $start_time}"
38
+ raise "Attempt #{message.attempts} for message #{message.data}" if message.attempts < $exceptions_limit
39
+ logger.info "Processing of message #{message.data} succeeded on attempt #{message.attempts}. completed: #{$completed += 1}"
40
+ end
41
+
42
+ # called when handler process raised an exception
43
+ def error(exception)
44
+ logger.info "Execution failed: #{exception}"
45
+ end
46
+ end
47
+
48
+ # register our handler to the message, configure it to our max_attempts limit, we configure a (base) delay of 1
49
+ client.register_handler(:test, Handler, exceptions: $exceptions_limit, delay: 1, max_delay: 10)
50
+
51
+ # publish test messages
52
+ client.publish(:test, 1) # publish returns the number of servers the message has been sent to
53
+ puts "Published 1 test message"
54
+
55
+ # start the listening loop
56
+ client.listen do
57
+ # catch INT-signal and stop listening
58
+ trap("INT") { client.stop_listening }
59
+ # we're adding a periodic timer to check whether all messages have been processed without exceptions
60
+ timer = EM.add_periodic_timer(1) do
61
+ if $completed == 1
62
+ timer.cancel
63
+ client.stop_listening
64
+ end
65
+ end
66
+ end
67
+
68
+ puts "Handled #{$completed} messages"
69
+ if $completed != 1
70
+ raise "Did not handle the correct number of messages"
71
+ end
72
+
@@ -46,6 +46,8 @@ module Beetle
46
46
  attr_reader :timeout
47
47
  # how long to wait before retrying the message handler
48
48
  attr_reader :delay
49
+ # maximum wait time for message handler retries (uses exponential backoff)
50
+ attr_reader :max_delay
49
51
  # how many times we should try to run the handler
50
52
  attr_reader :attempts_limit
51
53
  # how many exceptions we should tolerate before giving up
@@ -71,6 +73,8 @@ module Beetle
71
73
  @exceptions_limit = opts[:exceptions] || DEFAULT_EXCEPTION_LIMIT
72
74
  @attempts_limit = @exceptions_limit + 1 if @attempts_limit <= @exceptions_limit
73
75
  @store = opts[:store]
76
+ max_delay = opts[:max_delay] || @delay
77
+ @max_delay = max_delay if max_delay >= 2*@delay
74
78
  end
75
79
 
76
80
  # extracts various values from the AMQP header properties
@@ -186,7 +190,7 @@ module Beetle
186
190
 
187
191
  # store delay value in the deduplication store
188
192
  def set_delay!
189
- @store.set(msg_id, :delay, now + delay)
193
+ @store.set(msg_id, :delay, now + next_delay(attempts))
190
194
  end
191
195
 
192
196
  # how many times we already tried running the handler
@@ -362,5 +366,13 @@ module Beetle
362
366
  @store.del_keys(msg_id)
363
367
  end
364
368
  end
369
+
370
+ def next_delay(n)
371
+ if max_delay
372
+ [delay * (2**n), max_delay].min
373
+ else
374
+ delay
375
+ end
376
+ end
365
377
  end
366
378
  end
@@ -1,3 +1,3 @@
1
1
  module Beetle
2
- VERSION = "2.0.2"
2
+ VERSION = "2.1.0"
3
3
  end
@@ -0,0 +1,174 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
2
+
3
+ module Beetle
4
+ class SettingsTest < Minitest::Test
5
+ def setup
6
+ @store = DeduplicationStore.new
7
+ @store.flushdb
8
+ end
9
+
10
+ test "completed! should store the status 'complete' in the database" do
11
+ message = Message.new("somequeue", header_with_params, 'foo', :store => @store)
12
+ assert !message.completed?
13
+ message.completed!
14
+ assert message.completed?
15
+ assert_equal "completed", @store.get(message.msg_id, :status)
16
+ end
17
+
18
+ test "set_delay! should store the current time plus the delay offset in the database" do
19
+ message = Message.new("somequeue", header_with_params, 'foo', :delay => 2, :store => @store)
20
+ message.expects(:now).returns(9)
21
+ message.set_delay!
22
+ assert_equal "11", @store.get(message.msg_id, :delay)
23
+ message.expects(:now).returns(12)
24
+ assert !message.delayed?
25
+ message.expects(:now).returns(10)
26
+ assert message.delayed?
27
+ end
28
+
29
+ test "set_delay! should store the current time plus the exponential delay offset in the database" do
30
+ message = Message.new("somequeue", header_with_params, 'foo', :delay => 3, :max_delay => 30, :store => @store)
31
+ message.stubs(:now).returns(1)
32
+
33
+ [4, 7, 13, 25].each do |exp_delay|
34
+ message.set_delay!
35
+ assert_equal exp_delay, @store.get(message.msg_id, :delay).to_i
36
+ message.increment_execution_attempts!
37
+ end
38
+ end
39
+
40
+ test "set_delay! should store the current time plus the exponential delay offset in the database up to given max value" do
41
+ message = Message.new("somequeue", header_with_params, 'foo', :delay => 3, :max_delay => 10, :store => @store)
42
+ message.stubs(:now).returns(1)
43
+
44
+ [4, 7, 11, 11].each do |exp_delay|
45
+ message.set_delay!
46
+ assert_equal exp_delay, @store.get(message.msg_id, :delay).to_i
47
+ message.increment_execution_attempts!
48
+ end
49
+ end
50
+
51
+ test "set_delay! should store the current time plus the linear delay offset in the database" do
52
+ delay = 32
53
+ message = Message.new("somequeue", header_with_params, 'foo', :delay => delay, :store => @store)
54
+ [3, 5, 6].each do |now_offset|
55
+ message.stubs(:now).returns(now_offset)
56
+ message.set_delay!
57
+ assert_equal @store.get(message.msg_id, :delay).to_i, now_offset + delay
58
+ message.increment_execution_attempts!
59
+ end
60
+ end
61
+
62
+ test "set_delay! should use the default delay if the delay hasn't been set on the message instance" do
63
+ message = Message.new("somequeue", header_with_params, 'foo', :store => @store)
64
+ message.expects(:now).returns(0)
65
+ message.set_delay!
66
+ assert_equal "#{Message::DEFAULT_HANDLER_EXECUTION_ATTEMPTS_DELAY}", @store.get(message.msg_id, :delay)
67
+ message.expects(:now).returns(message.delay)
68
+ assert !message.delayed?
69
+ message.expects(:now).returns(0)
70
+ assert message.delayed?
71
+ end
72
+
73
+ test "set_timeout! should store the current time plus the number of timeout seconds in the database" do
74
+ message = Message.new("somequeue", header_with_params, 'foo', :timeout => 1, :store => @store)
75
+ message.expects(:now).returns(1)
76
+ message.set_timeout!
77
+ assert_equal "2", @store.get(message.msg_id, :timeout)
78
+ message.expects(:now).returns(2)
79
+ assert !message.timed_out?
80
+ message.expects(:now).returns(3)
81
+ assert message.timed_out?
82
+ end
83
+
84
+ test "set_timeout! should use the default timeout if the timeout hasn't been set on the message instance" do
85
+ message = Message.new("somequeue", header_with_params, 'foo', :store => @store)
86
+ message.expects(:now).returns(0)
87
+ message.set_timeout!
88
+ assert_equal "#{Message::DEFAULT_HANDLER_TIMEOUT}", @store.get(message.msg_id, :timeout)
89
+ message.expects(:now).returns(message.timeout)
90
+ assert !message.timed_out?
91
+ message.expects(:now).returns(Message::DEFAULT_HANDLER_TIMEOUT + 1)
92
+ assert message.timed_out?
93
+ end
94
+
95
+ test "incrementing execution attempts should increment by 1" do
96
+ message = Message.new("somequeue", header_with_params, 'foo', :store => @store)
97
+ assert_equal 1, message.increment_execution_attempts!
98
+ assert_equal 2, message.increment_execution_attempts!
99
+ assert_equal 3, message.increment_execution_attempts!
100
+ end
101
+
102
+ test "accessing execution attempts should return the number of execution attempts made so far" do
103
+ message = Message.new("somequeue", header_with_params, 'foo', :store => @store)
104
+ assert_equal 0, message.attempts
105
+ message.increment_execution_attempts!
106
+ assert_equal 1, message.attempts
107
+ message.increment_execution_attempts!
108
+ assert_equal 2, message.attempts
109
+ message.increment_execution_attempts!
110
+ assert_equal 3, message.attempts
111
+ end
112
+
113
+ test "accessing execution attempts should return 0 if none were made" do
114
+ message = Message.new("somequeue", header_with_params, 'foo', :store => @store)
115
+ assert_equal 0, message.attempts
116
+ end
117
+
118
+
119
+ test "attempts limit should be set exception limit + 1 iff the configured attempts limit is equal to or smaller than the exceptions limit" do
120
+ message = Message.new("somequeue", header_with_params, 'foo', :exceptions => 1, :store => @store)
121
+ assert_equal 2, message.attempts_limit
122
+ assert_equal 1, message.exceptions_limit
123
+ message = Message.new("somequeue", header_with_params, 'foo', :exceptions => 2, :store => @store)
124
+ assert_equal 3, message.attempts_limit
125
+ assert_equal 2, message.exceptions_limit
126
+ message = Message.new("somequeue", header_with_params, 'foo', :attempts => 5, :exceptions => 2, :store => @store)
127
+ assert_equal 5, message.attempts_limit
128
+ assert_equal 2, message.exceptions_limit
129
+ end
130
+
131
+ test "attempts limit should be reached after incrementing the attempt limit counter 'attempts limit' times" do
132
+ message = Message.new("somequeue", header_with_params, 'foo', :attempts =>2, :store => @store)
133
+ assert !message.attempts_limit_reached?
134
+ message.increment_execution_attempts!
135
+ assert !message.attempts_limit_reached?
136
+ message.increment_execution_attempts!
137
+ assert message.attempts_limit_reached?
138
+ message.increment_execution_attempts!
139
+ assert message.attempts_limit_reached?
140
+ end
141
+
142
+ test "incrementing exception counts should increment by 1" do
143
+ message = Message.new("somequeue", header_with_params, 'foo', :store => @store)
144
+ assert_equal 1, message.increment_exception_count!
145
+ assert_equal 2, message.increment_exception_count!
146
+ assert_equal 3, message.increment_exception_count!
147
+ end
148
+
149
+ test "default exceptions limit should be reached after incrementing the attempt limit counter 1 time" do
150
+ message = Message.new("somequeue", header_with_params, 'foo', :store => @store)
151
+ assert !message.exceptions_limit_reached?
152
+ message.increment_exception_count!
153
+ assert message.exceptions_limit_reached?
154
+ end
155
+
156
+ test "exceptions limit should be reached after incrementing the attempt limit counter 'exceptions limit + 1' times" do
157
+ message = Message.new("somequeue", header_with_params, 'foo', :exceptions => 1, :store => @store)
158
+ assert !message.exceptions_limit_reached?
159
+ message.increment_exception_count!
160
+ assert !message.exceptions_limit_reached?
161
+ message.increment_exception_count!
162
+ assert message.exceptions_limit_reached?
163
+ message.increment_exception_count!
164
+ assert message.exceptions_limit_reached?
165
+ end
166
+
167
+ test "failure to aquire a mutex should delete it from the database" do
168
+ message = Message.new("somequeue", header_with_params, 'foo', :store => @store)
169
+ assert message.aquire_mutex!
170
+ assert !message.aquire_mutex!
171
+ assert !@store.exists(message.msg_id, :mutex)
172
+ end
173
+ end
174
+ end
@@ -677,159 +677,6 @@ module Beetle
677
677
  end
678
678
  end
679
679
 
680
- class SettingsTest < Minitest::Test
681
- def setup
682
- @store = DeduplicationStore.new
683
- @store.flushdb
684
- end
685
-
686
- test "completed! should store the status 'complete' in the database" do
687
- header = header_with_params({})
688
- message = Message.new("somequeue", header, 'foo', :store => @store)
689
- assert !message.completed?
690
- message.completed!
691
- assert message.completed?
692
- assert_equal "completed", @store.get(message.msg_id, :status)
693
- end
694
-
695
- test "set_delay! should store the current time plus the number of delayed seconds in the database" do
696
- header = header_with_params({})
697
- message = Message.new("somequeue", header, 'foo', :delay => 1, :store => @store)
698
- message.expects(:now).returns(1)
699
- message.set_delay!
700
- assert_equal "2", @store.get(message.msg_id, :delay)
701
- message.expects(:now).returns(2)
702
- assert !message.delayed?
703
- message.expects(:now).returns(0)
704
- assert message.delayed?
705
- end
706
-
707
- test "set_delay! should use the default delay if the delay hasn't been set on the message instance" do
708
- header = header_with_params({})
709
- message = Message.new("somequeue", header, 'foo', :store => @store)
710
- message.expects(:now).returns(0)
711
- message.set_delay!
712
- assert_equal "#{Message::DEFAULT_HANDLER_EXECUTION_ATTEMPTS_DELAY}", @store.get(message.msg_id, :delay)
713
- message.expects(:now).returns(message.delay)
714
- assert !message.delayed?
715
- message.expects(:now).returns(0)
716
- assert message.delayed?
717
- end
718
-
719
- test "set_timeout! should store the current time plus the number of timeout seconds in the database" do
720
- header = header_with_params({})
721
- message = Message.new("somequeue", header, 'foo', :timeout => 1, :store => @store)
722
- message.expects(:now).returns(1)
723
- message.set_timeout!
724
- assert_equal "2", @store.get(message.msg_id, :timeout)
725
- message.expects(:now).returns(2)
726
- assert !message.timed_out?
727
- message.expects(:now).returns(3)
728
- assert message.timed_out?
729
- end
730
-
731
- test "set_timeout! should use the default timeout if the timeout hasn't been set on the message instance" do
732
- header = header_with_params({})
733
- message = Message.new("somequeue", header, 'foo', :store => @store)
734
- message.expects(:now).returns(0)
735
- message.set_timeout!
736
- assert_equal "#{Message::DEFAULT_HANDLER_TIMEOUT}", @store.get(message.msg_id, :timeout)
737
- message.expects(:now).returns(message.timeout)
738
- assert !message.timed_out?
739
- message.expects(:now).returns(Message::DEFAULT_HANDLER_TIMEOUT+1)
740
- assert message.timed_out?
741
- end
742
-
743
- test "incrementing execution attempts should increment by 1" do
744
- header = header_with_params({})
745
- message = Message.new("somequeue", header, 'foo', :store => @store)
746
- assert_equal 1, message.increment_execution_attempts!
747
- assert_equal 2, message.increment_execution_attempts!
748
- assert_equal 3, message.increment_execution_attempts!
749
- end
750
-
751
- test "accessing execution attempts should return the number of execution attempts made so far" do
752
- header = header_with_params({})
753
- message = Message.new("somequeue", header, 'foo', :store => @store)
754
- assert_equal 0, message.attempts
755
- message.increment_execution_attempts!
756
- assert_equal 1, message.attempts
757
- message.increment_execution_attempts!
758
- assert_equal 2, message.attempts
759
- message.increment_execution_attempts!
760
- assert_equal 3, message.attempts
761
- end
762
-
763
- test "accessing execution attempts should return 0 if none were made" do
764
- header = header_with_params({})
765
- message = Message.new("somequeue", header, 'foo', :store => @store)
766
- assert_equal 0, message.attempts
767
- end
768
-
769
-
770
- test "attempts limit should be set exception limit + 1 iff the configured attempts limit is equal to or smaller than the exceptions limit" do
771
- header = header_with_params({})
772
- message = Message.new("somequeue", header, 'foo', :exceptions => 1, :store => @store)
773
- assert_equal 2, message.attempts_limit
774
- assert_equal 1, message.exceptions_limit
775
- message = Message.new("somequeue", header, 'foo', :exceptions => 2, :store => @store)
776
- assert_equal 3, message.attempts_limit
777
- assert_equal 2, message.exceptions_limit
778
- message = Message.new("somequeue", header, 'foo', :attempts => 5, :exceptions => 2, :store => @store)
779
- assert_equal 5, message.attempts_limit
780
- assert_equal 2, message.exceptions_limit
781
- end
782
-
783
- test "attempts limit should be reached after incrementing the attempt limit counter 'attempts limit' times" do
784
- header = header_with_params({})
785
- message = Message.new("somequeue", header, 'foo', :attempts =>2, :store => @store)
786
- assert !message.attempts_limit_reached?
787
- message.increment_execution_attempts!
788
- assert !message.attempts_limit_reached?
789
- message.increment_execution_attempts!
790
- assert message.attempts_limit_reached?
791
- message.increment_execution_attempts!
792
- assert message.attempts_limit_reached?
793
- end
794
-
795
- test "incrementing exception counts should increment by 1" do
796
- header = header_with_params({})
797
- message = Message.new("somequeue", header, 'foo', :store => @store)
798
- assert_equal 1, message.increment_exception_count!
799
- assert_equal 2, message.increment_exception_count!
800
- assert_equal 3, message.increment_exception_count!
801
- end
802
-
803
- test "default exceptions limit should be reached after incrementing the attempt limit counter 1 time" do
804
- header = header_with_params({})
805
- message = Message.new("somequeue", header, 'foo', :store => @store)
806
- assert !message.exceptions_limit_reached?
807
- message.increment_exception_count!
808
- assert message.exceptions_limit_reached?
809
- end
810
-
811
- test "exceptions limit should be reached after incrementing the attempt limit counter 'exceptions limit + 1' times" do
812
- header = header_with_params({})
813
- message = Message.new("somequeue", header, 'foo', :exceptions => 1, :store => @store)
814
- assert !message.exceptions_limit_reached?
815
- message.increment_exception_count!
816
- assert !message.exceptions_limit_reached?
817
- message.increment_exception_count!
818
- assert message.exceptions_limit_reached?
819
- message.increment_exception_count!
820
- assert message.exceptions_limit_reached?
821
- end
822
-
823
- test "failure to aquire a mutex should delete it from the database" do
824
- header = header_with_params({})
825
- message = Message.new("somequeue", header, 'foo', :store => @store)
826
- assert message.aquire_mutex!
827
- assert !message.aquire_mutex!
828
- assert !@store.exists(message.msg_id, :mutex)
829
- end
830
- end
831
-
832
-
833
680
  class RoutingKeyTest < Minitest::Test
834
681
  test "returns the routing key" do
835
682
  header = header_with_params({})
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: 2.0.2
4
+ version: 2.1.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: 2017-09-25 00:00:00.000000000 Z
15
+ date: 2017-12-01 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: uuid4r
@@ -314,6 +314,8 @@ files:
314
314
  - beetle.gemspec
315
315
  - examples/README.rdoc
316
316
  - examples/attempts.rb
317
+ - examples/attempts_with_dead_letter_and_exponential_backoff.rb
318
+ - examples/attempts_with_exponential_backoff.rb
317
319
  - examples/consume_many_messages_and_shutdown_randomly.rb
318
320
  - examples/handler_class.rb
319
321
  - examples/handling_exceptions.rb
@@ -361,6 +363,7 @@ files:
361
363
  - test/beetle/dead_lettering_test.rb
362
364
  - test/beetle/deduplication_store_test.rb
363
365
  - test/beetle/handler_test.rb
366
+ - test/beetle/message/settings_test.rb
364
367
  - test/beetle/message_test.rb
365
368
  - test/beetle/publisher_test.rb
366
369
  - test/beetle/r_c_test.rb
@@ -389,7 +392,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
389
392
  version: 1.3.7
390
393
  requirements: []
391
394
  rubyforge_project:
392
- rubygems_version: 2.6.13
395
+ rubygems_version: 2.6.14
393
396
  signing_key:
394
397
  specification_version: 3
395
398
  summary: High Availability AMQP Messaging with Redundant Queues
@@ -402,6 +405,7 @@ test_files:
402
405
  - test/beetle/dead_lettering_test.rb
403
406
  - test/beetle/deduplication_store_test.rb
404
407
  - test/beetle/handler_test.rb
408
+ - test/beetle/message/settings_test.rb
405
409
  - test/beetle/message_test.rb
406
410
  - test/beetle/publisher_test.rb
407
411
  - test/beetle/r_c_test.rb