Files
tidb/pkg/util/backoff/backoff.go
2025-05-06 01:32:31 +00:00

59 lines
1.7 KiB
Go

// Copyright 2023 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package backoff
import "time"
// Backoffer is the interface to get backoff.
type Backoffer interface {
// Backoff returns the duration to wait for the retryCnt-th retry.
// retryCnt starts from 0.
Backoff(retryCnt int) time.Duration
}
// Exponential implements the exponential backoff algorithm without jitter.
// should create one instance for each operation that need retry.
type Exponential struct {
baseBackoff time.Duration
multiplier float64
maxBackoff time.Duration
nextBackoff time.Duration
}
var _ Backoffer = &Exponential{}
// NewExponential creates a new Exponential backoff.
func NewExponential(baseBackoff time.Duration, multiplier float64, maxBackoff time.Duration) *Exponential {
return &Exponential{
baseBackoff: baseBackoff,
multiplier: multiplier,
maxBackoff: maxBackoff,
nextBackoff: baseBackoff,
}
}
// Backoff returns the duration to wait for the retryCnt-th retry.
// retryCnt starts from 0.
func (b *Exponential) Backoff(retryCnt int) time.Duration {
if retryCnt == 0 {
b.nextBackoff = b.baseBackoff
return b.nextBackoff
}
b.nextBackoff = min(time.Duration(float64(b.nextBackoff)*b.multiplier), b.maxBackoff)
return b.nextBackoff
}