mirror of https://github.com/tikv/client-go.git
add retry limit for excluded backoff type to avoid infinite retry (#1002)
* add retry limit for excluded backoff type to avoid infinite retry Signed-off-by: cfzjywxk <lsswxrxr@163.com> * change log Signed-off-by: cfzjywxk <lsswxrxr@163.com> --------- Signed-off-by: cfzjywxk <lsswxrxr@163.com>
This commit is contained in:
parent
2eaf68e0cd
commit
888cbb283e
|
|
@ -143,7 +143,13 @@ func (b *Backoffer) BackoffWithCfgAndMaxSleep(cfg *Config, maxSleepMs int, err e
|
||||||
if b.noop {
|
if b.noop {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if b.maxSleep > 0 && (b.totalSleep-b.excludedSleep) >= b.maxSleep {
|
maxBackoffTimeExceeded := (b.totalSleep - b.excludedSleep) >= b.maxSleep
|
||||||
|
maxExcludedTimeExceeded := false
|
||||||
|
if maxLimit, ok := isSleepExcluded[cfg.name]; ok {
|
||||||
|
maxExcludedTimeExceeded = b.excludedSleep >= maxLimit && b.excludedSleep >= b.maxSleep
|
||||||
|
}
|
||||||
|
maxTimeExceeded := maxBackoffTimeExceeded || maxExcludedTimeExceeded
|
||||||
|
if b.maxSleep > 0 && maxTimeExceeded {
|
||||||
longestSleepCfg, longestSleepTime := b.longestSleepCfg()
|
longestSleepCfg, longestSleepTime := b.longestSleepCfg()
|
||||||
errMsg := fmt.Sprintf("%s backoffer.maxSleep %dms is exceeded, errors:", cfg.String(), b.maxSleep)
|
errMsg := fmt.Sprintf("%s backoffer.maxSleep %dms is exceeded, errors:", cfg.String(), b.maxSleep)
|
||||||
for i, err := range b.errors {
|
for i, err := range b.errors {
|
||||||
|
|
@ -163,7 +169,8 @@ func (b *Backoffer) BackoffWithCfgAndMaxSleep(cfg *Config, maxSleepMs int, err e
|
||||||
backoffDetail.WriteString(":")
|
backoffDetail.WriteString(":")
|
||||||
backoffDetail.WriteString(strconv.Itoa(times))
|
backoffDetail.WriteString(strconv.Itoa(times))
|
||||||
}
|
}
|
||||||
errMsg += fmt.Sprintf("\ntotal-backoff-times: %v, backoff-detail: %v", totalTimes, backoffDetail.String())
|
errMsg += fmt.Sprintf("\ntotal-backoff-times: %v, backoff-detail: %v, maxBackoffTimeExceeded: %v, maxExcludedTimeExceeded: %v",
|
||||||
|
totalTimes, backoffDetail.String(), maxBackoffTimeExceeded, maxExcludedTimeExceeded)
|
||||||
returnedErr := err
|
returnedErr := err
|
||||||
if longestSleepCfg != nil {
|
if longestSleepCfg != nil {
|
||||||
errMsg += fmt.Sprintf("\nlongest sleep type: %s, time: %dms", longestSleepCfg.String(), longestSleepTime)
|
errMsg += fmt.Sprintf("\nlongest sleep type: %s, time: %dms", longestSleepCfg.String(), longestSleepTime)
|
||||||
|
|
|
||||||
|
|
@ -98,3 +98,15 @@ func TestBackoffDeepCopy(t *testing.T) {
|
||||||
assert.ErrorIs(t, err, BoMaxDataNotReady.err)
|
assert.ErrorIs(t, err, BoMaxDataNotReady.err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBackoffWithMaxExcludedExceed(t *testing.T) {
|
||||||
|
setBackoffExcluded(BoTiKVServerBusy.name, 1)
|
||||||
|
b := NewBackofferWithVars(context.TODO(), 1, nil)
|
||||||
|
err := b.Backoff(BoTiKVServerBusy, errors.New("server is busy"))
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
// As the total excluded sleep is greater than the max limited value, error should be returned.
|
||||||
|
err = b.Backoff(BoTiKVServerBusy, errors.New("server is busy"))
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
assert.Greater(t, b.excludedSleep, b.maxSleep)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -130,11 +130,18 @@ var (
|
||||||
BoTxnLockFast = NewConfig(txnLockFastName, &metrics.BackoffHistogramLockFast, NewBackoffFnCfg(2, 3000, EqualJitter), tikverr.ErrResolveLockTimeout)
|
BoTxnLockFast = NewConfig(txnLockFastName, &metrics.BackoffHistogramLockFast, NewBackoffFnCfg(2, 3000, EqualJitter), tikverr.ErrResolveLockTimeout)
|
||||||
)
|
)
|
||||||
|
|
||||||
var isSleepExcluded = map[string]struct{}{
|
var isSleepExcluded = map[string]int{
|
||||||
BoTiKVServerBusy.name: {},
|
BoTiKVServerBusy.name: 600000, // The max excluded limit is 10min.
|
||||||
// add BoTiFlashServerBusy if appropriate
|
// add BoTiFlashServerBusy if appropriate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setBackoffExcluded is used for test only.
|
||||||
|
func setBackoffExcluded(name string, maxVal int) {
|
||||||
|
if _, ok := isSleepExcluded[name]; ok {
|
||||||
|
isSleepExcluded[name] = maxVal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// NoJitter makes the backoff sequence strict exponential.
|
// NoJitter makes the backoff sequence strict exponential.
|
||||||
NoJitter = 1 + iota
|
NoJitter = 1 + iota
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue