sidekiq-rescue 0.6.0 → 0.7.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: f7e9209b0b3fcb19ae0068540e6a83aedf56928457fd53584e6ebf7397ef541a
4
- data.tar.gz: debef2495e57e1452f19982777fb2238f75c811ab48a161f36858beff7f7a7e1
3
+ metadata.gz: 73ef52e3781eb80768b2ed8d3271ad8665537fb893d98d77a60b702377c8db08
4
+ data.tar.gz: c3a4bcb2bbbf95511379a8a0890a306e04c5cff10f1f13582352f82b2f25ecb3
5
5
  SHA512:
6
- metadata.gz: 96620e97aeabdfb9bc0ed8df29216e5017409c28e126e0e41d3941b3dde8548b5a4ecf0c1e54253f6280a8046291f21e2110ab3c514673f26cb1a557b895f754
7
- data.tar.gz: a01212d26bdfb69c4dd3377a89fdeae379f8a016d8e98087b5c916528e0a54191bdff9b99d5e41330e81b7d971aea0da18fcde7058d1f727d525ac57e29d72b6
6
+ metadata.gz: 32ce0eb6087e28f9ee95550e88f70d9ab2b808a516652673d5731fbcbdf61fe918425a294346c0eb81c775dcfde23086816776ff82ed669ebb5f778690a30a90
7
+ data.tar.gz: 6146c192a03de08da8e4da68a7b81adfe7e2d3de2142df62a83002d367208619a2a9d292107ade101af972a8b667588770f45218bee7da5b5d342cb672575efe
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.7.0] - 2026-04-18
4
+
5
+ - Add `:polynomially_longer` built-in delay strategy for polynomial backoff (`executions**4 + 2` base, with configurable jitter) [#8](https://github.com/moofkit/sidekiq-rescue/pull/8)
6
+ - Add `:exponentially_longer` built-in delay strategy for exponential backoff (`2**executions` base, with configurable jitter) [#14](https://github.com/moofkit/sidekiq-rescue/pull/14)
7
+ - Bump and pin github actions [#15](https://github.com/moofkit/sidekiq-rescue/pull/14)
8
+
3
9
  ## [0.6.0] - 2025-03-15
4
10
  - Add support for Sidekiq 8.0, Ruby 3.4 [#6](https://github.com/moofkit/sidekiq-rescue/pull/6)
5
11
 
@@ -40,7 +46,8 @@
40
46
  - Add documentation
41
47
  - Add CI
42
48
 
43
- [Unreleased]: https://github.com/moofkit/sidekiq-rescue/compare/v0.6.0...HEAD
49
+ [Unreleased]: https://github.com/moofkit/sidekiq-rescue/compare/v0.7.0...HEAD
50
+ [0.6.0]: https://github.com/moofkit/sidekiq-rescue/releases/tag/v0.7.0
44
51
  [0.6.0]: https://github.com/moofkit/sidekiq-rescue/releases/tag/v0.6.0
45
52
  [0.5.0]: https://github.com/moofkit/sidekiq-rescue/releases/tag/v0.5.0
46
53
  [0.4.0]: https://github.com/moofkit/sidekiq-rescue/releases/tag/v0.4.0
data/README.md CHANGED
@@ -20,6 +20,7 @@ class MyJob
20
20
  sidekiq_rescue ActiveRecord::Deadlocked, delay: 5.seconds.to_i, limit: 3
21
21
  sidekiq_rescue TooManyRequestsError, queue: "slow"
22
22
  sidekiq_rescue Net::OpenTimeout, Timeout::Error, limit: 10 # retries at most 10 times for Net::OpenTimeout and Timeout::Error combined
23
+ sidekiq_rescue FlakyServiceError, delay: :polynomially_longer
23
24
 
24
25
  def perform(*args)
25
26
  # Might raise CustomAppException, AnotherCustomAppException, or YetAnotherCustomAppException for something domain specific
@@ -91,16 +92,16 @@ class MyJob
91
92
  end
92
93
  ```
93
94
 
94
- * `delay` - the delay between retries in seconds
95
+ * `delay` - the delay between retries in seconds. Accepts an `Integer`, `Float`, `Proc` (receives the retry counter), or a built-in strategy symbol (see **Built-in delay strategies** below).
95
96
  * `limit` - the number of retries. The number of attempts includes the original job execution.
96
97
  * `jitter` - represents the upper bound of possible wait time (expressed as a percentage) and defaults to 0.15 (15%)
97
98
  * `queue` - the queue to which the job will be enqueued if it fails
98
99
 
99
- The `delay` is not the exact time between retries, but a minimum delay. The actual delay calculates based on jitter and `delay` value. The formula is `delay + delay * jitter * rand` seconds. Randomization is used to avoid retry storms.
100
+ The `delay` is not the exact time between retries, but a minimum delay. For fixed and proc-based delays, the actual delay is `delay + delay * jitter * rand` seconds. Randomization is used to avoid retry storms. Built-in delay strategy symbols define their own formulas.
100
101
 
101
102
  The default values are:
102
103
  - `delay`: 60 seconds
103
- - `limit`: 5 retries
104
+ - `limit`: 10 retries
104
105
  - `jitter`: 0.15
105
106
 
106
107
  Delay, limit and jitter can be configured globally:
@@ -127,6 +128,48 @@ Sidekiq::Rescue.configure do |config|
127
128
  end
128
129
  ```
129
130
 
131
+ ### Built-in delay strategies
132
+
133
+ The `delay:` option accepts the following built-in strategy symbols:
134
+
135
+ #### `:polynomially_longer`
136
+
137
+ Applies a polynomial backoff formula: `(executions**4 + 2) + (Kernel.rand * (executions**4 + 2) * jitter)`
138
+
139
+ The `jitter:` option controls randomness (same semantics as for fixed delays). Setting `jitter: 0` makes the delay deterministic.
140
+
141
+ | Attempt | Approx. delay (default jitter) |
142
+ |---------|-------------------------------|
143
+ | 1 | ~3s |
144
+ | 2 | ~18s |
145
+ | 3 | ~83s |
146
+ | 4 | ~260s (~4m) |
147
+ | 5 | ~627s (~10m) |
148
+
149
+ ```ruby
150
+ sidekiq_rescue FlakyServiceError, delay: :polynomially_longer
151
+ sidekiq_rescue FlakyServiceError, delay: :polynomially_longer, jitter: 0 # deterministic
152
+ ```
153
+
154
+ #### `:exponentially_longer`
155
+
156
+ Applies an exponential backoff formula: `(2**executions) + (Kernel.rand * (2**executions) * jitter)`
157
+
158
+ The `jitter:` option controls randomness. Setting `jitter: 0` makes the delay deterministic.
159
+
160
+ | Attempt | Delay (jitter: 0) | Approx. delay (default jitter) |
161
+ |---------|-------------------|-------------------------------|
162
+ | 1 | 2s | ~2s |
163
+ | 2 | 4s | ~4s |
164
+ | 3 | 8s | ~9s |
165
+ | 4 | 16s | ~18s |
166
+ | 5 | 32s | ~37s |
167
+
168
+ ```ruby
169
+ sidekiq_rescue FlakyServiceError, delay: :exponentially_longer
170
+ sidekiq_rescue FlakyServiceError, delay: :exponentially_longer, jitter: 0 # deterministic
171
+ ```
172
+
130
173
  ### Testing
131
174
 
132
175
  1. Unit tests (recommended)
@@ -2,6 +2,8 @@
2
2
 
3
3
  module Sidekiq
4
4
  module Rescue
5
+ DELAY_STRATEGIES = %i[polynomially_longer exponentially_longer].freeze
6
+
5
7
  # This module is included into the job class to provide the Dsl for
6
8
  # configuring rescue options.
7
9
  module Dsl
@@ -15,7 +17,8 @@ module Sidekiq
15
17
  # Configure rescue options for the job.
16
18
  # @param error [StandardError] The error class to rescue.
17
19
  # @param error [Array<StandardError>] The error classes to rescue.
18
- # @param delay [Integer, Float, Proc] The delay in seconds before retrying the job.
20
+ # @param delay [Integer, Float, Proc, Symbol] The delay in seconds before retrying the job.
21
+ # Symbols like `:polynomially_longer` or `:exponentially_longer` are built-in delay strategies.
19
22
  # @param limit [Integer] The maximum number of retries.
20
23
  # @return [void]
21
24
  # @raise [ArgumentError] if error is not a StandardError
@@ -66,8 +69,10 @@ module Sidekiq
66
69
  return
67
70
  end
68
71
 
72
+ return if delay.is_a?(Symbol) && DELAY_STRATEGIES.include?(delay)
73
+
69
74
  raise ArgumentError,
70
- "delay must be integer, float or proc"
75
+ "delay must be integer, float, proc, or one of: #{DELAY_STRATEGIES.join(", ")}"
71
76
  end
72
77
 
73
78
  def validate_limit_argument(limit)
@@ -49,9 +49,13 @@ module Sidekiq
49
49
  end
50
50
 
51
51
  def calculate_delay(delay, rescue_counter, jitter)
52
- delay = delay.call(rescue_counter) if delay.is_a?(Proc)
53
- jitter_delay = calculate_delay_jitter(jitter, delay)
54
- delay + jitter_delay
52
+ base = case delay
53
+ when :polynomially_longer then (rescue_counter**4) + 2
54
+ when :exponentially_longer then 2**rescue_counter
55
+ when Proc then delay.call(rescue_counter)
56
+ else delay
57
+ end
58
+ base + calculate_delay_jitter(jitter, base)
55
59
  end
56
60
 
57
61
  def calculate_delay_jitter(jitter, delay)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Sidekiq
4
4
  module Rescue
5
- VERSION = "0.6.0"
5
+ VERSION = "0.7.0"
6
6
  end
7
7
  end
@@ -30,6 +30,7 @@ module Sidekiq
30
30
 
31
31
  class << self
32
32
  extend Forwardable
33
+
33
34
  # Returns the logger instance
34
35
  #
35
36
  # @return [Logger] The logger instance.
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sidekiq-rescue
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dmitrii Ivliev
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-03-15 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: sidekiq
@@ -48,7 +48,7 @@ metadata:
48
48
  homepage_uri: https://github.com/moofkit/sidekiq-rescue
49
49
  source_code_uri: https://github.com/moofkit/sidekiq-rescue
50
50
  changelog_uri: https://github.com/moofkit/sidekiq-rescue/blob/master/CHANGELOG.md
51
- documentation_uri: https://rubydoc.info/gems/sidekiq-rescue/0.6.0
51
+ documentation_uri: https://rubydoc.info/gems/sidekiq-rescue/0.7.0
52
52
  rubygems_mfa_required: 'true'
53
53
  rdoc_options: []
54
54
  require_paths:
@@ -64,7 +64,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
64
64
  - !ruby/object:Gem::Version
65
65
  version: '0'
66
66
  requirements: []
67
- rubygems_version: 3.6.2
67
+ rubygems_version: 4.0.3
68
68
  specification_version: 4
69
69
  summary: Rescue Sidekiq jobs on expected error and reschedule them
70
70
  test_files: []