beetle 2.0.2 → 2.1.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
  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