stream: add jitter to retry backoff in accordance with gRFC A6 (#7869)

This commit is contained in:
Ismail Gjevori 2024-11-27 00:08:44 +01:00 committed by GitHub
parent 967ba46140
commit 4c07bca273
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 8 additions and 8 deletions

View File

@ -168,6 +168,7 @@ func init() {
return parseServiceConfig(js, defaultMaxCallAttempts) return parseServiceConfig(js, defaultMaxCallAttempts)
} }
} }
func parseServiceConfig(js string, maxAttempts int) *serviceconfig.ParseResult { func parseServiceConfig(js string, maxAttempts int) *serviceconfig.ParseResult {
if len(js) == 0 { if len(js) == 0 {
return &serviceconfig.ParseResult{Err: fmt.Errorf("no JSON service config provided")} return &serviceconfig.ParseResult{Err: fmt.Errorf("no JSON service config provided")}
@ -297,7 +298,7 @@ func convertRetryPolicy(jrp *jsonRetryPolicy, maxAttempts int) (p *internalservi
return rp, nil return rp, nil
} }
func min(a, b *int) *int { func minPointers(a, b *int) *int {
if *a < *b { if *a < *b {
return a return a
} }
@ -309,7 +310,7 @@ func getMaxSize(mcMax, doptMax *int, defaultVal int) *int {
return &defaultVal return &defaultVal
} }
if mcMax != nil && doptMax != nil { if mcMax != nil && doptMax != nil {
return min(mcMax, doptMax) return minPointers(mcMax, doptMax)
} }
if mcMax != nil { if mcMax != nil {
return mcMax return mcMax

View File

@ -218,7 +218,7 @@ func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth
var mc serviceconfig.MethodConfig var mc serviceconfig.MethodConfig
var onCommit func() var onCommit func()
var newStream = func(ctx context.Context, done func()) (iresolver.ClientStream, error) { newStream := func(ctx context.Context, done func()) (iresolver.ClientStream, error) {
return newClientStreamWithParams(ctx, desc, cc, method, mc, onCommit, done, opts...) return newClientStreamWithParams(ctx, desc, cc, method, mc, onCommit, done, opts...)
} }
@ -708,11 +708,10 @@ func (a *csAttempt) shouldRetry(err error) (bool, error) {
cs.numRetriesSincePushback = 0 cs.numRetriesSincePushback = 0
} else { } else {
fact := math.Pow(rp.BackoffMultiplier, float64(cs.numRetriesSincePushback)) fact := math.Pow(rp.BackoffMultiplier, float64(cs.numRetriesSincePushback))
cur := float64(rp.InitialBackoff) * fact cur := min(float64(rp.InitialBackoff)*fact, float64(rp.MaxBackoff))
if max := float64(rp.MaxBackoff); cur > max { // Apply jitter by multiplying with a random factor between 0.8 and 1.2
cur = max cur *= 0.8 + 0.4*rand.Float64()
} dur = time.Duration(int64(cur))
dur = time.Duration(rand.Int64N(int64(cur)))
cs.numRetriesSincePushback++ cs.numRetriesSincePushback++
} }