Skip to content

Commit 860eb5d

Browse files
committed
chore(deps): pin delivery backoff max branch
Signed-off-by: kahirokunn <okinakahiro@gmail.com>
1 parent 3e64d06 commit 860eb5d

8 files changed

Lines changed: 108 additions & 8 deletions

File tree

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,5 @@ require (
130130
sigs.k8s.io/randfill v1.0.0 // indirect
131131
sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect
132132
)
133+
134+
replace knative.dev/eventing => github.com/kahirokunn/knative-eventing v0.0.0-20260821080516-828cffcff320

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,8 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm
320320
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
321321
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
322322
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
323+
github.com/kahirokunn/knative-eventing v0.0.0-20260821080516-828cffcff320 h1:vdKDX5EHiufGVgmzdIyqS6KFW82/Oxw3zW74XM4Qig0=
324+
github.com/kahirokunn/knative-eventing v0.0.0-20260821080516-828cffcff320/go.mod h1:HC1K7A1oa/sMd6X6RHO547NgvL2gtKlmNK+HYnELz6g=
323325
github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=
324326
github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
325327
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
@@ -1074,8 +1076,6 @@ k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZ
10741076
k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ=
10751077
k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck=
10761078
k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
1077-
knative.dev/eventing v0.50.1-0.20260820115420-72ec4f420db1 h1:N61jbMWe2eUDVBnXP2beXD0OmUGSxb75NTfhAtBeS8o=
1078-
knative.dev/eventing v0.50.1-0.20260820115420-72ec4f420db1/go.mod h1:HC1K7A1oa/sMd6X6RHO547NgvL2gtKlmNK+HYnELz6g=
10791079
knative.dev/hack v0.0.0-20260428014158-b2a37f1b6e7b h1:MvbV2F2BdI8qKrYYUhDwbUZbX0BAYRSIpXM2TOtTvs0=
10801080
knative.dev/hack v0.0.0-20260428014158-b2a37f1b6e7b/go.mod h1:L5RzHgbvam0u8QFHfzCX6MKxu/a/gIGEdaRBqNiVbl0=
10811081
knative.dev/pkg v0.0.0-20260820190123-c9015f8bfdea h1:vNg/ixrFn2UMDAh727Ag26G3jZAQGskbn5VOwZvKoOM=

vendor/knative.dev/eventing/pkg/apis/duck/v1/delivery_types.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,22 @@ type DeliverySpec struct {
6262
// +optional
6363
BackoffDelay *string `json:"backoffDelay,omitempty"`
6464

65+
// BackoffMax is the maximum delay between normal delivery attempts. It caps
66+
// the delay calculated from BackoffDelay and BackoffPolicy, but does not cap
67+
// delays requested by a Retry-After response header. The value must be
68+
// greater than zero.
69+
//
70+
// Note: This API is EXPERIMENTAL and might be changed at any time. Cluster
71+
// operators must enable the delivery-backoff-max feature before users can set
72+
// this field.
73+
//
74+
// More information on Duration format:
75+
// - https://www.iso.org/iso-8601-date-and-time-format.html
76+
// - https://en.wikipedia.org/wiki/ISO_8601
77+
//
78+
// +optional
79+
BackoffMax *string `json:"backoffMax,omitempty"`
80+
6581
// RetryAfterMax provides an optional upper bound on the duration specified in a "Retry-After" header
6682
// when calculating backoff times for retrying 429 and 503 response codes. Setting the value to
6783
// zero ("PT0S") can be used to opt-out of respecting "Retry-After" header values altogether. This
@@ -131,6 +147,17 @@ func (ds *DeliverySpec) Validate(ctx context.Context) *apis.FieldError {
131147
}
132148
}
133149

150+
if ds.BackoffMax != nil {
151+
if feature.FromContext(ctx).IsEnabled(feature.DeliveryBackoffMax) {
152+
p, pe := period.Parse(*ds.BackoffMax)
153+
if pe != nil || p.IsZero() || p.IsNegative() {
154+
errs = errs.Also(apis.ErrInvalidValue(*ds.BackoffMax, "backoffMax"))
155+
}
156+
} else {
157+
errs = errs.Also(apis.ErrDisallowedFields("backoffMax"))
158+
}
159+
}
160+
134161
if ds.Format != nil {
135162
switch *ds.Format {
136163
case DeliveryFormatBinary, DeliveryFormatJson:

vendor/knative.dev/eventing/pkg/apis/duck/v1/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/knative.dev/eventing/pkg/apis/feature/features.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ func newDefaults() Flags {
8181
return map[string]Flag{
8282
KReferenceGroup: Disabled,
8383
DeliveryRetryAfter: Disabled,
84+
DeliveryBackoffMax: Disabled,
8485
DeliveryTimeout: Enabled,
8586
KReferenceMapping: Disabled,
8687
TransportEncryption: Disabled,

vendor/knative.dev/eventing/pkg/apis/feature/flag_names.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package feature
1919
const (
2020
KReferenceGroup = "kreference-group"
2121
DeliveryRetryAfter = "delivery-retryafter"
22+
DeliveryBackoffMax = "delivery-backoff-max"
2223
DeliveryTimeout = "delivery-timeout"
2324
KReferenceMapping = "kreference-mapping"
2425
TransportEncryption = "transport-encryption"

vendor/knative.dev/eventing/pkg/kncloudevents/retries.go

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ package kncloudevents
1919
import (
2020
"context"
2121
"fmt"
22-
"math"
2322
"net/http"
2423
"strconv"
2524
"time"
@@ -58,11 +57,12 @@ type Backoff func(attemptNum int, resp *http.Response) time.Duration
5857
type RetryConfig struct {
5958
// Maximum number of retries
6059
RetryMax int
61-
// These next two variables are just copied from the original DeliverySpec so
60+
// These next three variables are just copied from the original DeliverySpec so
6261
// we can detect if anything has changed. We can not do that with the CheckRetry
6362
// Backoff (at least not easily).
6463
BackoffDelay *string
6564
BackoffPolicy *v1.BackoffPolicyType
65+
BackoffMax *string
6666

6767
CheckRetry CheckRetry
6868
Backoff Backoff
@@ -92,6 +92,20 @@ func RetryConfigFromDeliverySpec(spec v1.DeliverySpec) (RetryConfig, error) {
9292
}
9393
retryConfig.BackoffPolicy = spec.BackoffPolicy
9494
retryConfig.BackoffDelay = spec.BackoffDelay
95+
retryConfig.BackoffMax = spec.BackoffMax
96+
97+
var backoffMaxDuration *time.Duration
98+
if spec.BackoffMax != nil {
99+
maxPeriod, err := period.Parse(*spec.BackoffMax)
100+
if err != nil || maxPeriod.IsZero() || maxPeriod.IsNegative() {
101+
if err != nil {
102+
return retryConfig, fmt.Errorf("failed to parse Spec.BackoffMax: %w", err)
103+
}
104+
return retryConfig, fmt.Errorf("Spec.BackoffMax must be greater than zero")
105+
}
106+
maxDelay := saturatingPeriodDuration(maxPeriod)
107+
backoffMaxDuration = &maxDelay
108+
}
95109

96110
if spec.BackoffPolicy != nil && spec.BackoffDelay != nil {
97111

@@ -100,15 +114,15 @@ func RetryConfigFromDeliverySpec(spec v1.DeliverySpec) (RetryConfig, error) {
100114
return retryConfig, fmt.Errorf("failed to parse Spec.BackoffDelay: %w", err)
101115
}
102116

103-
delayDuration, _ := delay.Duration()
117+
delayDuration := saturatingPeriodDuration(delay)
104118
switch *spec.BackoffPolicy {
105119
case v1.BackoffPolicyExponential:
106120
retryConfig.Backoff = func(attemptNum int, resp *http.Response) time.Duration {
107-
return delayDuration * time.Duration(math.Exp2(float64(attemptNum)))
121+
return exponentialBackoff(delayDuration, attemptNum, backoffMaxDuration)
108122
}
109123
case v1.BackoffPolicyLinear:
110124
retryConfig.Backoff = func(attemptNum int, resp *http.Response) time.Duration {
111-
return delayDuration * time.Duration(attemptNum)
125+
return linearBackoff(delayDuration, attemptNum, backoffMaxDuration)
112126
}
113127
}
114128
}
@@ -133,6 +147,55 @@ func RetryConfigFromDeliverySpec(spec v1.DeliverySpec) (RetryConfig, error) {
133147
return retryConfig, nil
134148
}
135149

150+
const maxBackoffDuration = time.Duration(1<<63 - 1)
151+
152+
func saturatingPeriodDuration(p period.Period) time.Duration {
153+
if p.IsPositive() && p.TotalDaysApprox() > int(maxBackoffDuration/(24*time.Hour)) {
154+
return maxBackoffDuration
155+
}
156+
157+
d, _ := p.Duration()
158+
if p.IsPositive() && d < 0 {
159+
return maxBackoffDuration
160+
}
161+
return d
162+
}
163+
164+
func linearBackoff(delay time.Duration, attemptNum int, configuredMax *time.Duration) time.Duration {
165+
if attemptNum <= 0 || delay <= 0 {
166+
return 0
167+
}
168+
limit := maxBackoffDuration
169+
if configuredMax != nil {
170+
limit = *configuredMax
171+
}
172+
if delay >= limit || time.Duration(attemptNum) > limit/delay {
173+
return limit
174+
}
175+
return delay * time.Duration(attemptNum)
176+
}
177+
178+
func exponentialBackoff(delay time.Duration, attemptNum int, configuredMax *time.Duration) time.Duration {
179+
if attemptNum < 0 || delay <= 0 {
180+
return 0
181+
}
182+
limit := maxBackoffDuration
183+
if configuredMax != nil {
184+
limit = *configuredMax
185+
}
186+
if delay >= limit {
187+
return limit
188+
}
189+
result := delay
190+
for range attemptNum {
191+
if result > limit/2 {
192+
return limit
193+
}
194+
result *= 2
195+
}
196+
return result
197+
}
198+
136199
// SelectiveRetry is an alternative function to determine whether to retry based on response
137200
//
138201
// Note - Returning true indicates a retry should occur. Returning an error will result in that

vendor/modules.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1212,7 +1212,7 @@ k8s.io/utils/net
12121212
k8s.io/utils/pointer
12131213
k8s.io/utils/ptr
12141214
k8s.io/utils/trace
1215-
# knative.dev/eventing v0.50.1-0.20260820115420-72ec4f420db1
1215+
# knative.dev/eventing v0.50.1-0.20260820115420-72ec4f420db1 => github.com/kahirokunn/knative-eventing v0.0.0-20260821080516-828cffcff320
12161216
## explicit; go 1.25.0
12171217
knative.dev/eventing/pkg/apis
12181218
knative.dev/eventing/pkg/apis/common/integration/v1alpha1
@@ -1460,3 +1460,4 @@ sigs.k8s.io/structured-merge-diff/v6/value
14601460
# sigs.k8s.io/yaml v1.6.0
14611461
## explicit; go 1.22
14621462
sigs.k8s.io/yaml
1463+
# knative.dev/eventing => github.com/kahirokunn/knative-eventing v0.0.0-20260821080516-828cffcff320

0 commit comments

Comments
 (0)