philiprehberger-webhook_builder 0.4.0 → 0.5.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: 5c3d746e099083b6d9da206ce5b4630ca0a4c5ee2c4f1f99373af3c992d89c38
4
- data.tar.gz: 23ed5e8d7b8e40f27a71cf7f4cb42c91d501ef8a5028d39d0a77cd1d08a589be
3
+ metadata.gz: b3008661457c2c68b820bfb48c133cc513040bb2f5ec35af8e62a4c0318241c9
4
+ data.tar.gz: 461cbff339dfd9fab1bccf97e68c855080ee48f3faa685fc92b2aab81c56aeb2
5
5
  SHA512:
6
- metadata.gz: 7e503cd54a9fb91a78879f0ccd541a24b91a447ca30ba89c7d832a4c757d07de2a35e7c0066c8c0e13c01b130f6765afdc96b4b8e234c4ba60d492aba2d3e536
7
- data.tar.gz: 6f9942dc1678940173ab109c17b236f83bf14087ed1dae8880f17a2703e8e89a87c2455e752ea7c9b6aff14f6992bd408db65bd46b0499729ec8644d27e7d561
6
+ metadata.gz: f68594c755f2995c19390964a63ae42ef14832eefca6a0de3c54deb74a6fd1641908bccbfd11e00b7bc4592a303fd95c552fbb7adfe652a94e7a6dac49c724bd
7
+ data.tar.gz: 8f6b0914eab043887af35ea57a03a7f85b2d72d0c7cbc3f8d4eecb7746a31c98ba49c0dbe6983784a07f1cb5e06bfc34094b6e302039ee2af77edf2a2ab1a29b
data/CHANGELOG.md CHANGED
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.5.0] - 2026-05-08
11
+
12
+ ### Added
13
+ - `Backoff::Decorrelated` — AWS-style decorrelated jitter strategy (`delay = base + rand * (min(cap, prev * 3) - base)`); spreads retries to avoid thundering-herd patterns
14
+ - `Client#new(backoff: :decorrelated)` — `:decorrelated` is now a recognized symbol alongside `:exponential`, `:linear`, `:fixed`, and any callable Proc
15
+
10
16
  ## [0.4.0] - 2026-04-22
11
17
 
12
18
  ### Added
data/README.md CHANGED
@@ -86,6 +86,13 @@ client = Philiprehberger::WebhookBuilder.new(
86
86
  backoff: :fixed
87
87
  )
88
88
 
89
+ # Decorrelated jitter (AWS-style): randomized within [base, min(cap, prev*3)]
90
+ client = Philiprehberger::WebhookBuilder.new(
91
+ url: "https://example.com/webhooks",
92
+ secret: "secret",
93
+ backoff: :decorrelated
94
+ )
95
+
89
96
  # Custom Proc backoff
90
97
  client = Philiprehberger::WebhookBuilder.new(
91
98
  url: "https://example.com/webhooks",
@@ -216,6 +223,13 @@ delivery.error # => nil or error message
216
223
  | `.new(delay:)` | Create fixed strategy (default: delay=1) |
217
224
  | `#call(attempt)` | Returns constant delay |
218
225
 
226
+ ### `Backoff::Decorrelated`
227
+
228
+ | Method | Description |
229
+ |--------|-------------|
230
+ | `.new(base:, max_delay:)` | Create decorrelated jitter strategy (defaults: base=1, max_delay=30) |
231
+ | `#call(attempt)` | Returns randomized delay in `[base, min(max_delay, prev * 3)]` |
232
+
219
233
  ## Development
220
234
 
221
235
  ```bash
@@ -53,6 +53,30 @@ module Philiprehberger
53
53
  end
54
54
  end
55
55
 
56
+ # Decorrelated jitter backoff (AWS-style): each delay is a random value
57
+ # in `[base, [cap, prev * 3].min]`, which spreads retries to avoid
58
+ # thundering-herd effects while still trending toward the cap.
59
+ #
60
+ # See: https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/
61
+ class Decorrelated
62
+ # @param base [Numeric] minimum delay in seconds (default: 1)
63
+ # @param max_delay [Numeric] maximum delay in seconds (default: 30)
64
+ def initialize(base: 1, max_delay: 30)
65
+ @base = base.to_f
66
+ @max_delay = max_delay.to_f
67
+ @prev = @base
68
+ end
69
+
70
+ # @param _attempt [Integer] ignored (state is carried in @prev)
71
+ # @return [Float] delay in seconds
72
+ def call(_attempt)
73
+ upper = [@max_delay, @prev * 3].min
74
+ upper = @base if upper < @base
75
+ @prev = @base + (rand * (upper - @base))
76
+ @prev
77
+ end
78
+ end
79
+
56
80
  # Resolve a backoff option into a callable strategy.
57
81
  #
58
82
  # @param option [Symbol, Proc, nil] the backoff strategy
@@ -65,10 +89,14 @@ module Philiprehberger
65
89
  Linear.new
66
90
  when :fixed
67
91
  Fixed.new
92
+ when :decorrelated
93
+ Decorrelated.new
68
94
  when Proc
69
95
  option
70
96
  else
71
- raise ArgumentError, "Unknown backoff strategy: #{option.inspect}. Use :exponential, :linear, :fixed, or a Proc."
97
+ raise ArgumentError,
98
+ "Unknown backoff strategy: #{option.inspect}. " \
99
+ 'Use :exponential, :linear, :fixed, :decorrelated, or a Proc.'
72
100
  end
73
101
  end
74
102
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Philiprehberger
4
4
  module WebhookBuilder
5
- VERSION = '0.4.0'
5
+ VERSION = '0.5.0'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: philiprehberger-webhook_builder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Philip Rehberger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-04-22 00:00:00.000000000 Z
11
+ date: 2026-05-08 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A webhook delivery client that signs payloads with HMAC-SHA256, retries
14
14
  failed deliveries with configurable backoff strategies, supports batch delivery,