Update dependencies and bump Go to v1.24.10

This commit is contained in:
Ciprian Hacman
2025-11-29 11:15:51 +02:00
parent b0d347e262
commit 6b19393e1c
362 changed files with 20314 additions and 29260 deletions
+1 -1
View File
@@ -1 +1 @@
4.6.1
4.7.0
+31
View File
@@ -124,6 +124,8 @@ func BackOffDelay(n uint, _ error, config *Config) time.Duration {
config.maxBackOffN = max - uint(math.Floor(math.Log2(float64(config.delay))))
}
n--
if n > config.maxBackOffN {
n = config.maxBackOffN
}
@@ -158,6 +160,35 @@ func CombineDelay(delays ...DelayTypeFunc) DelayTypeFunc {
}
}
// FullJitterBackoffDelay is a DelayTypeFunc that calculates delay using exponential backoff
// with full jitter. The delay is a random value between 0 and the current backoff ceiling.
// Formula: sleep = random_between(0, min(cap, base * 2^attempt))
// It uses config.Delay as the base delay and config.MaxDelay as the cap.
func FullJitterBackoffDelay(n uint, err error, config *Config) time.Duration {
// Calculate the exponential backoff ceiling for the current attempt
backoffCeiling := float64(config.delay) * math.Pow(2, float64(n))
currentCap := float64(config.maxDelay)
// If MaxDelay is set and backoffCeiling exceeds it, cap at MaxDelay
if currentCap > 0 && backoffCeiling > currentCap {
backoffCeiling = currentCap
}
// Ensure backoffCeiling is at least 0
if backoffCeiling < 0 {
backoffCeiling = 0
}
// Add jitter: random value between 0 and backoffCeiling
// rand.Int63n panics if argument is <= 0
if backoffCeiling <= 0 {
return 0 // No delay if ceiling is zero or negative
}
jitter := rand.Int63n(int64(backoffCeiling)) // #nosec G404 -- Using math/rand is acceptable for non-security critical jitter.
return time.Duration(jitter)
}
// OnRetry function callback are called each retry
//
// log each retry example:
+11 -11
View File
@@ -132,7 +132,7 @@ func DoWithData[T any](retryableFunc RetryableFuncWithData[T], opts ...Option) (
opt(config)
}
if err := config.context.Err(); err != nil {
if err := context.Cause(config.context); err != nil {
return emptyT, err
}
@@ -161,9 +161,9 @@ func DoWithData[T any](retryableFunc RetryableFuncWithData[T], opts ...Option) (
case <-config.timer.After(delay(config, n, err)):
case <-config.context.Done():
if config.wrapContextErrorWithLastError {
return emptyT, Error{config.context.Err(), lastErr}
return emptyT, Error{context.Cause(config.context), lastErr}
}
return emptyT, config.context.Err()
return emptyT, context.Cause(config.context)
}
}
}
@@ -175,8 +175,8 @@ func DoWithData[T any](retryableFunc RetryableFuncWithData[T], opts ...Option) (
attemptsForError[err] = attempts
}
shouldRetry := true
for shouldRetry {
shouldRetry:
for {
t, err := retryableFunc()
if err == nil {
return t, nil
@@ -194,26 +194,26 @@ func DoWithData[T any](retryableFunc RetryableFuncWithData[T], opts ...Option) (
if errors.Is(err, errToCheck) {
attempts--
attemptsForError[errToCheck] = attempts
shouldRetry = shouldRetry && attempts > 0
if attempts <= 0 {
break shouldRetry
}
}
}
// if this is last attempt - don't wait
if n == config.attempts-1 {
break
break shouldRetry
}
n++
select {
case <-config.timer.After(delay(config, n, err)):
case <-config.context.Done():
if config.lastErrorOnly {
return emptyT, config.context.Err()
return emptyT, context.Cause(config.context)
}
return emptyT, append(errorLog, config.context.Err())
return emptyT, append(errorLog, context.Cause(config.context))
}
shouldRetry = shouldRetry && n < config.attempts
}
if config.lastErrorOnly {