Skip to content

Commit b1b2f49

Browse files
authored
Revert "Remove RetryLoopCas since RetryLoop behaves identically (#7823)" (#7837)
1 parent 2a0746e commit b1b2f49

File tree

3 files changed

+43
-10
lines changed

3 files changed

+43
-10
lines changed

base/collection_xattr.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ func (c *Collection) SubdocGetRaw(ctx context.Context, k string, subdocKey strin
148148
return false, nil, uint64(res.Cas())
149149
}
150150

151-
err, casOut := RetryLoop(ctx, "SubdocGetRaw", worker, DefaultRetrySleeper())
151+
err, casOut := RetryLoopCas(ctx, "SubdocGetRaw", worker, DefaultRetrySleeper())
152152
if err != nil {
153153
err = pkgerrors.Wrapf(err, "SubdocGetRaw with key %s and subdocKey %s", UD(k).Redact(), UD(subdocKey).Redact())
154154
}
@@ -181,7 +181,7 @@ func (c *Collection) SubdocWrite(ctx context.Context, k string, subdocKey string
181181
return false, err, 0
182182
}
183183

184-
err, casOut := RetryLoop(ctx, "SubdocWrite", worker, DefaultRetrySleeper())
184+
err, casOut := RetryLoopCas(ctx, "SubdocWrite", worker, DefaultRetrySleeper())
185185
if err != nil {
186186
err = pkgerrors.Wrapf(err, "SubdocWrite with key %s and subdocKey %s", UD(k).Redact(), UD(subdocKey).Redact())
187187
}
@@ -310,7 +310,7 @@ func (c *Collection) subdocGetBodyAndXattrs(ctx context.Context, k string, xattr
310310
}
311311

312312
// Kick off retry loop
313-
err, cas = RetryLoop(ctx, "subdocGetBodyAndXattrs", worker, DefaultRetrySleeper())
313+
err, cas = RetryLoopCas(ctx, "subdocGetBodyAndXattrs", worker, DefaultRetrySleeper())
314314
if err != nil {
315315
err = pkgerrors.Wrapf(err, "subdocGetBodyAndXattrs %v", UD(k).Redact())
316316
}

base/collection_xattr_common.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ func (c *Collection) WriteWithXattrs(ctx context.Context, k string, exp uint32,
6161
}
6262

6363
// Kick off retry loop
64-
err, cas = RetryLoop(ctx, "WriteWithXattrs", worker, DefaultRetrySleeper())
64+
err, cas = RetryLoopCas(ctx, "WriteWithXattrs", worker, DefaultRetrySleeper())
6565
if err != nil {
6666
err = pkgerrors.Wrapf(err, "WriteWithXattrs with key %v", UD(k).Redact())
6767
}
@@ -111,7 +111,7 @@ func (c *Collection) WriteTombstoneWithXattrs(ctx context.Context, k string, exp
111111
}
112112

113113
// Kick off retry loop
114-
err, cas = RetryLoop(ctx, "WriteTombstoneWithXattrs", worker, DefaultRetrySleeper())
114+
err, cas = RetryLoopCas(ctx, "WriteTombstoneWithXattrs", worker, DefaultRetrySleeper())
115115
if err != nil {
116116
err = pkgerrors.Wrapf(err, "Error during WriteTombstoneXattrs with key %v", UD(k).Redact())
117117
return cas, err
@@ -138,7 +138,7 @@ func (c *Collection) WriteTombstoneWithXattrs(ctx context.Context, k string, exp
138138
return false, nil, casOut
139139
}
140140

141-
err, cas = RetryLoop(ctx, "UpdateXattrDeleteBodySecondOp", worker, DefaultRetrySleeper())
141+
err, cas = RetryLoopCas(ctx, "UpdateXattrDeleteBodySecondOp", worker, DefaultRetrySleeper())
142142
if err != nil {
143143
err = pkgerrors.Wrapf(err, "Error during UpdateTombstoneXattr delete op with key %v", UD(k).Redact())
144144
return cas, err
@@ -165,7 +165,7 @@ func (c *Collection) WriteResurrectionWithXattrs(ctx context.Context, k string,
165165
}
166166

167167
// Kick off retry loop
168-
err, cas := RetryLoop(ctx, "WriteResurrectionWithXattrs", worker, DefaultRetrySleeper())
168+
err, cas := RetryLoopCas(ctx, "WriteResurrectionWithXattrs", worker, DefaultRetrySleeper())
169169
if err != nil {
170170
err = pkgerrors.Wrapf(err, "WriteResurrectionWithXattrs with key %v", UD(k).Redact())
171171
}
@@ -297,7 +297,7 @@ func SetXattrs(ctx context.Context, store *Collection, k string, xvs map[string]
297297
return false, writeErr, 0
298298
}
299299

300-
err, casOut = RetryLoop(ctx, "SetXattr", worker, DefaultRetrySleeper())
300+
err, casOut = RetryLoopCas(ctx, "SetXattr", worker, DefaultRetrySleeper())
301301
if err != nil {
302302
err = pkgerrors.Wrapf(err, "SetXattr with key %v", UD(k).Redact())
303303
}

base/util.go

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,8 @@ type RetrySleeper func(retryCount int) (shouldContinue bool, timeTosleepMs int)
427427
// even if it returns shouldRetry = true.
428428
type RetryWorker[T any] func() (shouldRetry bool, err error, value T)
429429

430+
type RetryCasWorker func() (shouldRetry bool, err error, value uint64)
431+
430432
type RetryTimeoutError struct {
431433
description string
432434
attempts int
@@ -483,6 +485,37 @@ func RetryLoop[T any](ctx context.Context, description string, worker RetryWorke
483485
}
484486
}
485487

488+
// A version of RetryLoop that returns a strongly typed cas as uint64, to avoid interface conversion overhead for
489+
// high throughput operations.
490+
func RetryLoopCas(ctx context.Context, description string, worker RetryCasWorker, sleeper RetrySleeper) (error, uint64) {
491+
492+
numAttempts := 1
493+
494+
for {
495+
shouldRetry, err, value := worker()
496+
if !shouldRetry {
497+
if err != nil {
498+
return err, value
499+
}
500+
return nil, value
501+
}
502+
shouldContinue, sleepMs := sleeper(numAttempts)
503+
if !shouldContinue {
504+
if err == nil {
505+
err = NewRetryTimeoutError(description, numAttempts)
506+
}
507+
WarnfCtx(ctx, "RetryLoopCas for %v giving up after %v attempts", description, numAttempts)
508+
return err, value
509+
}
510+
DebugfCtx(ctx, KeyAll, "RetryLoopCas retrying %v after %v ms.", description, sleepMs)
511+
512+
<-time.After(time.Millisecond * time.Duration(sleepMs))
513+
514+
numAttempts += 1
515+
516+
}
517+
}
518+
486519
// SleeperFuncCtx wraps the given RetrySleeper with a context, so it can be cancelled, or have a deadline.
487520
func SleeperFuncCtx(sleeperFunc RetrySleeper, ctx context.Context) RetrySleeper {
488521
return func(retryCount int) (bool, int) {
@@ -514,7 +547,7 @@ func CreateDoublingSleeperFunc(maxNumAttempts, initialTimeToSleepMs int) RetrySl
514547

515548
}
516549

517-
// CreateDoublingSleeperDurationFunc creates a RetrySleeper that will double the retry time on every iteration with
550+
// Create a RetrySleeper that will double the retry time on every iteration with
518551
// initial sleep time and a total max wait no longer than maxWait
519552
func CreateDoublingSleeperDurationFunc(initialTimeToSleepMs int, maxWait time.Duration) RetrySleeper {
520553

@@ -555,7 +588,7 @@ func CreateLinearSleeperFunc(totalTime, timeToSleep time.Duration) RetrySleeper
555588
return CreateSleeperFunc(int(totalTime.Seconds()/timeToSleep.Seconds()), int(timeToSleep.Milliseconds()))
556589
}
557590

558-
// CreateMaxDoublingSleeperFunc creates a RetrySleeper that will double the retry time on every iteration, with each sleep not exceeding maxSleepPerRetryMs.
591+
// Create a RetrySleeper that will double the retry time on every iteration, with each sleep not exceeding maxSleepPerRetryMs.
559592
func CreateMaxDoublingSleeperFunc(maxNumAttempts, initialTimeToSleepMs int, maxSleepPerRetryMs int) RetrySleeper {
560593

561594
timeToSleepMs := initialTimeToSleepMs

0 commit comments

Comments
 (0)