eventq 2.0.3 → 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
  SHA256:
3
- metadata.gz: bbf0fcaf93e6ca42d1fa190d4880b3416f1e32481950b1817cf3e97b87f7e465
4
- data.tar.gz: be23ab444cbc536d1aa0f3996f2209ee5409e19c1d8b5e98f8a79ad7736d531d
3
+ metadata.gz: 946df3b90ab1e50b46c3e3c1732b0e82c7adfe67468e1a49b08d6fa761a0cce9
4
+ data.tar.gz: 3fcf13525865b2896f73c3088de352d6658b2b9dbf0754acc06412f8d5d9fcba
5
5
  SHA512:
6
- metadata.gz: af21be2b6e181e44241efc06733c025c7fae3ba65062e39a7ae34e5c07e16a7887751c9bfc8c6853eec973030fdb23059c74804f2ad4e8dbb40c64adf5ebeb87
7
- data.tar.gz: df647d0e20c6adb7c99499fbdd21e106a127d6912e01f9a71a1eb5931191b4976b6e67d0a49604200dd999ec8fa38ca9a98eae2a240e5147d0f72fe8259bdec4
6
+ metadata.gz: ed166219545af071b020b6bd8268c0a2a0da4f8727b2751fbd4b72d3350cfe5503c0ac885dd177aef4272f837d869cfe8a7bfbdc7931a2fc196ce15072e4bc87
7
+ data.tar.gz: 002dce7368948f01ef23a9cfa9756c7de082e31978811bdfde91a1ba4a68501d0620237160254f85af9d2d8acc6ea7042c502af0253163400a7ea50761998ca1
data/README.md CHANGED
@@ -54,7 +54,7 @@ A subscription queue should be defined to receive any events raised for the subs
54
54
  **Attributes**
55
55
 
56
56
  - **allow_retry** [Bool] [Optional] [Default=false] This determines if the queue should allow processing failures to be retried.
57
- - **allow_retry_backoff** [Bool] [Optional] [Default=false] This is used to specify if failed messages that retry should incrementally backoff.
57
+ - **allow_retry_back_off** [Bool] [Optional] [Default=false] This is used to specify if failed messages that retry should incrementally backoff.
58
58
  - **retry_back_off_grace** [Int] [Optional] [Default=0] This is the number of times to allow retries without applying retry back off if enabled.
59
59
  - **dlq** [EventQ::Queue] [Optional] [Default=nil] A queue that will receive the messages which were not successfully processed after maximum number of receives by consumers. This is created at the same time as the parent queue.
60
60
  - **max_retry_attempts** [Int] [Optional] [Default=5] This is used to specify the max number of times an event should be allowed to retry before failing.
@@ -63,6 +63,7 @@ A subscription queue should be defined to receive any events raised for the subs
63
63
  - **name** [String] [Required] This is the name of the queue, it must be unique.
64
64
  - **require_signature** [Bool] [Optional] [Default=false] This is used to specify if messages within this queue must be signed.
65
65
  - **retry_delay** [Int] [Optional] [Default=30000] This is used to specify the time delay in milliseconds before a failed message is re-added to the subscription queue.
66
+ - **retry_back_off_weight** [Int] [Optional] [Default=1] Additional multiplier for the timeout backoff. Normally used when `retry_delay` is too small (eg: 30ms) in order to get meaningful backoff values.
66
67
 
67
68
  **Example**
68
69
 
@@ -254,7 +255,7 @@ This is used to specify the signature secret that should be used for message sig
254
255
 
255
256
  ### NonceManager
256
257
 
257
- The NonceManager is used to prevent duplicate messages from being processed. Each event message that is raised is given a unique identifier, most message queue providers guarantee at least once delivery which may result in the message being delivered more than once. If your use case needs to enforce once only processing then
258
+ The NonceManager is used to prevent duplicate messages from being processed. Each event message that is raised is given a unique identifier, most message queue providers guarantee at least once delivery which may result in the message being delivered more than once. If your use case needs to enforce once only processing then
258
259
  the NonceManager can be configured to prevent duplicate messages from being processed. (It is a distributed store that currently uses redis locks to ensure accuracy between scaled out workers)
259
260
 
260
261
  #### configure
@@ -1,6 +1,7 @@
1
1
  require 'aws-sdk-core'
2
2
  require 'eventq'
3
3
 
4
+ require_relative './eventq_aws/aws_calculate_visibility_timeout'
4
5
  require_relative './eventq_aws/aws_eventq_client'
5
6
  require_relative './eventq_aws/sns'
6
7
  require_relative './eventq_aws/sqs'
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EventQ
4
+ module Amazon
5
+ # Class responsible to know how to calculate message Visibility Timeout for Amazon SQS
6
+ class CalculateVisibilityTimeout
7
+ def initialize(max_timeout:, logger: EventQ.logger)
8
+ @max_timeout = max_timeout
9
+ @logger = logger
10
+ end
11
+
12
+ # Calculate Visibility Timeout
13
+ #
14
+ # @param retry_attempts [Integer] Current retry
15
+ # @param queue_settings [Hash] Queue settings
16
+ # @option allow_retry_back_off [Bool] Enables/Disables backoff strategy
17
+ # @option max_retry_delay [Integer] Maximum amount of time a retry will take in ms
18
+ # @option retry_back_off_grace [Integer] Amount of retries to wait before starting to backoff
19
+ # @option retry_back_off_weight [Integer] Multiplier for the backoff retry
20
+ # @option retry_delay [Integer] Amount of time to wait until retry in ms
21
+ # @return [Integer] the calculated visibility timeout in seconds
22
+ def call(retry_attempts:, queue_settings:)
23
+ @retry_attempts = retry_attempts
24
+
25
+ @allow_retry_back_off = queue_settings.fetch(:allow_retry_back_off)
26
+ @max_retry_delay = queue_settings.fetch(:max_retry_delay)
27
+ @retry_back_off_grace = queue_settings.fetch(:retry_back_off_grace)
28
+ @retry_back_off_weight= queue_settings.fetch(:retry_back_off_weight)
29
+ @retry_delay = queue_settings.fetch(:retry_delay)
30
+
31
+ if @allow_retry_back_off && retry_past_grace_period?
32
+ visibility_timeout = timeout_with_back_off
33
+ visibility_timeout = check_for_max_timeout(visibility_timeout)
34
+ else
35
+ visibility_timeout = timeout_without_back_off
36
+ end
37
+
38
+ visibility_timeout
39
+ end
40
+
41
+ private
42
+
43
+ attr_reader :logger
44
+
45
+ def retry_past_grace_period?
46
+ @retry_attempts > @retry_back_off_grace
47
+ end
48
+
49
+ def timeout_without_back_off
50
+ ms_to_seconds(@retry_delay)
51
+ end
52
+
53
+ def timeout_with_back_off
54
+ factor = @retry_attempts - @retry_back_off_grace
55
+
56
+ visibility_timeout = ms_to_seconds(@retry_delay * factor * @retry_back_off_weight)
57
+ max_retry_delay = ms_to_seconds(@max_retry_delay)
58
+
59
+ if visibility_timeout > max_retry_delay
60
+ logger.debug { "[#{self.class}] - Max message back off retry delay reached: #{max_retry_delay}" }
61
+ visibility_timeout = max_retry_delay
62
+ end
63
+
64
+ visibility_timeout
65
+ end
66
+
67
+ def ms_to_seconds(value)
68
+ value / 1000
69
+ end
70
+
71
+ def check_for_max_timeout(visibility_timeout)
72
+ if visibility_timeout > @max_timeout
73
+ logger.debug { "[#{self.class}] - AWS max visibility timeout of 12 hours has been exceeded. Setting message retry delay to 12 hours." }
74
+ visibility_timeout = @max_timeout
75
+ end
76
+ visibility_timeout
77
+ end
78
+ end
79
+ end
80
+ end
@@ -9,12 +9,16 @@ module EventQ
9
9
 
10
10
  APPROXIMATE_RECEIVE_COUNT = 'ApproximateReceiveCount'
11
11
  MESSAGE = 'Message'
12
+ AWS_MAX_VISIBILITY_TIMEOUT = 43_200 # 12h
12
13
 
13
14
  attr_accessor :context
14
15
 
15
16
  def initialize
16
17
  @serialization_provider_manager = EventQ::SerializationProviders::Manager.new
17
18
  @signature_provider_manager = EventQ::SignatureProviders::Manager.new
19
+ @calculate_visibility_timeout = Amazon::CalculateVisibilityTimeout.new(
20
+ max_timeout: AWS_MAX_VISIBILITY_TIMEOUT
21
+ )
18
22
  end
19
23
 
20
24
  def pre_process(context, options)
@@ -114,23 +118,16 @@ module EventQ
114
118
 
115
119
  EventQ.logger.info("[#{self.class}] - Message rejected requesting retry. Attempts: #{retry_attempts}")
116
120
 
117
- retry_attempts = retry_attempts - queue.retry_back_off_grace
118
- retry_attempts = 1 if retry_attempts < 1
119
-
120
- if queue.allow_retry_back_off == true
121
- visibility_timeout = (queue.retry_delay * retry_attempts) / 1000
122
- if visibility_timeout > (queue.max_retry_delay / 1000)
123
- EventQ.logger.debug { "[#{self.class}] - Max message back off retry delay reached." }
124
- visibility_timeout = queue.max_retry_delay / 1000
125
- end
126
- else
127
- visibility_timeout = queue.retry_delay / 1000
128
- end
129
-
130
- if visibility_timeout > 43200
131
- EventQ.logger.debug { "[#{self.class}] - AWS max visibility timeout of 12 hours has been exceeded. Setting message retry delay to 12 hours." }
132
- visibility_timeout = 43200
133
- end
121
+ visibility_timeout = @calculate_visibility_timeout.call(
122
+ retry_attempts: retry_attempts,
123
+ queue_settings: {
124
+ allow_retry_back_off: queue.allow_retry_back_off,
125
+ max_retry_delay: queue.max_retry_delay,
126
+ retry_back_off_grace: queue.retry_back_off_grace,
127
+ retry_back_off_weight: queue.retry_back_off_weight,
128
+ retry_delay: queue.retry_delay
129
+ }
130
+ )
134
131
 
135
132
  EventQ.logger.debug { "[#{self.class}] - Sending message for retry. Message TTL: #{visibility_timeout}" }
136
133
  poller.change_message_visibility_timeout(msg, visibility_timeout)
@@ -10,6 +10,7 @@ module EventQ
10
10
  attr_accessor :require_signature
11
11
  attr_accessor :retry_delay
12
12
  attr_accessor :retry_back_off_grace
13
+ attr_accessor :retry_back_off_weight
13
14
 
14
15
  def initialize
15
16
  @allow_retry = false
@@ -25,6 +26,8 @@ module EventQ
25
26
  @retry_delay = 30000
26
27
  # This is the amount of times to allow retry to occurr before back off is implemented
27
28
  @retry_back_off_grace = 0
29
+ # Multiplier for the backoff retry in case retry_delay is too small
30
+ @retry_back_off_weight = 1
28
31
  end
29
32
  end
30
33
  end
@@ -3,7 +3,6 @@ module EventQ
3
3
  class OjSerializationProvider
4
4
 
5
5
  def initialize
6
- require 'oj'
7
6
  @json_serializer = EventQ::SerializationProviders::JsonSerializationProvider.new
8
7
  end
9
8
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eventq
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.3
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - SageOne
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-11-30 00:00:00.000000000 Z
11
+ date: 2018-12-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -205,6 +205,7 @@ files:
205
205
  - bin/setup
206
206
  - lib/eventq.rb
207
207
  - lib/eventq/aws.rb
208
+ - lib/eventq/eventq_aws/aws_calculate_visibility_timeout.rb
208
209
  - lib/eventq/eventq_aws/aws_eventq_client.rb
209
210
  - lib/eventq/eventq_aws/aws_queue_client.rb
210
211
  - lib/eventq/eventq_aws/aws_queue_manager.rb