wait包位于github.com/kubernetes/apimachinery/pkg/util/wait,提供了通过监听一个条件的变化执行指定函数的工具函数.。 这些函数可以分为四大类:
Until 类: 根据 channel 的关闭或者 context.Done 的信号 来决定函数是否继续执行(能够控制开始时/完成时计时,建议JitterUntilWithContext);
Poll 类:根据 channel 的关闭或者 函数的返回值 来决定函数是否继续执行(函数执行遇到错误能够直接退出,建议PollImmediate);
Wait 类: 根据 WaitFor 函数返回的 channel 来触发函数执行(可以自由控制函数执行时机,建议WaitForWithContext);
Backoff 类:根据 Backoff 返回的时间间隔来循环触发函数的执行(可以限制次数,建议ExponentialBackoffWithContext)。
Jitter函数
在介绍具体函数前,介绍一下对时间间隔进行抖动干扰的函数 Jitter
func Jitter(duration time.Duration, maxFactor float64) time.Duration {
if maxFactor <= 0.0 {
maxFactor = 1.0
}
return duration + time.Duration(rand.Float64()*maxFactor*float64(duration))
}
Jitter
会返回一个 [duration, (duration+maxFactor*duration) )
区间的时间间隔
Until 类
根据 channel 的关闭或者 context.Done 的信号 来决定函数是否继续轮询执行(能够控制开始时/完成时计时,建议JitterUntilWithContext)
until 类
的函数参数都具有相同的意义
-
f
表示具体执行的函数 -
period
表示轮询的时间间隔 -
jitterFactor
表示对轮询时间间隔加一个抖动Jitter(period, jitterFactor)
-
sliding
为 True 表示执行函数的时间间隔是从f
函数执行就开始计时,False 表示f
函数执行完成后开始计时 -
stopCh
表示当stopCh
被关闭则结束轮询 -
ctx
表示当 ctx.Done 是结束函数的轮询
根据函数名称可以一些规律:
Jitter*
表示带时间抖动参数 jitterFactor
NoSliding*
即sliding为false,表示时间间隔从 f
函数执行完成后开始计时
Until*
即sliding为true,表示时间间隔从 f
函数执行就开始计时
函数 | 作用 |
---|---|
func JitterUntil (f func(), period time.Duration, jitterFactor float64, sliding bool, stopCh <-chan struct{}) | 先执行 f 之后会再等待 period 的时间 |
func JitterUntilWithContext (ctx context.Context, f func(context.Context), period time.Duration, jitterFactor float64, sliding bool) | |
func Until (f func(), period time.Duration, stopCh <-chan struct{}) | 相当于 sliding 为 True ,无抖动的 JitterUntil |
func NoSlidingUntil (f func(), period time.Duration, stopCh <-chan struct{}) | sliding 为 False |
func UntilWithContext (ctx context.Context, f func(context.Context), period time.Duration) | |
func NoSlidingUntilWithContext (ctx context.Context, f func(context.Context), period time.Duration) | |
func Forever (f func(), period time.Duration) | 永久轮询执行 f ,相当于 Until(f, period, NeverStop) |
建议直接全参数的 JitterUntilWithContext
Poll 类型
根据 channel 的关闭 或者 轮询函数的返回值 来决定函数是否继续轮询执行(函数执行遇到错误能够直接退出,建议PollImmediate)
当调用 ConditionFunc
返回 true
或者 error
时,结束对 ConditionFunc
的轮询,并且如果 ConditionFunc
返回了 error 那么Poll*
也会返回该错误
Poll 类型的轮询函数同样具有一些相同意义的参数:
-
interval
为执行ConditionFunc
的时间间隔 -
timeout
表示 Poll 类型函数的总执行超时时间,如果在timeout
时间内ConditionFunc
都没有返回true
或者error
时,返回ErrWaitTimeout
函数 | 作用 |
---|---|
func Poll (interval , timeout time.Duration, condition ConditionFunc) error | 在执行 ConditionFunc 之前会先等待 interval 的时间 |
func PollUntil (interval time.Duration, condition ConditionFunc, stopCh <-chan struct{}) error | 监听 stopCh 的 Poll |
func PollImmediate (interval , timeount time.Duration, condition ConditionFunc) error | 先执行 ConditionFunc 之后会再等待 interval 的时间 |
func PollImmediateInfinite (interval time.Duration, condition ConditionFunc) error | 没有过期时间的 PollImmediate |
func PollImmediateUntil (interval time.Duration, condition ConditionFunc, stopCh <- chan struct{}) error | 监听 stopCh 是否关闭 的 PollImmediate |
Poll*
和 PollImmediate*
两种函数的区别是: PollImmediate*
会先执行 ConditionFunc
,然后在等待 interval
的时间,而 Poll*
会先等待 interval
再执行ConditionFunc
建议直接全参数的 PollImmediate
,其实完全可以被Util类型函数替代。
Wait类型
根据 WaitFor 函数返回的 channel 来触发函数执行(可以自由控制函数执行时机,建议WaitForWithContext)
WaitFor(wait WaitFunc, fn ConditionFunc, done <-chan struct{}) error
WaitFunc
返回一个 channel,当 channel 每可读一次时会执行一次 ConditionFunc
,如果 channel 已被关闭,则退出ConditionFunc
。
当 done
关闭时,会直接返回 ErrorWaitTimeout。
Backoff类型
根据 Backoff 返回的时间间隔来循环触发函数的执行(可以限制次数,建议ExponentialBackoffWithContext)
type Backoff struct {
// 时间间隔,用于调用 Step 方法时返回的时间间隔
Duration time.Duration
// 用于计算下次的时间间隔
// Factor 大于 0 时,Backoff 在计算下次的时间间隔时都会根据 Duration * Factor,Factor * Duration 不能大于 Cap
// 不能为负数
Factor float64
// Jitter > 0 时,每次迭代的时间间隔都会额外加上 0 - Duration * Jitter 的随机时间,并且抖动出的时间不会设置为 Duration,而且不受 Caps 的限制
Jitter float64
// 进行指数回退(*Factor) 操作的次数
// 当 Factor * Duration > Cap 时 Steps 会被设置为 0, Duration 设置为 Cap
// 也就是说后续的迭代时间间隔都会返回 Duration
Steps int
// 最大的时间间隔
Cap time.Duration
}
BackoffManger
定义了 Backoff
方法,返回一个定时器,用于触发函数的执行。
func BackUntil (f func(), backoff BackoffManager, sliding book, stopCh <-chan struct{}) | 根据 Backoff 的定时器来循环触发 f ,直到 stopCh 关闭 |
func ExponentialBackoff (backoff Backoff, condition ConditionFunc) error | 根据 backoff 的时间间隔来循环执行 f |
func ExponentialBackoffWithContext (ctx context.Context, backoff Backoff, condition ConditionFunc) error |