// Returns True if the elapsed time since eventTime is smaller than the current backoff window func(p *Backoff) IsInBackOffSince(id string, eventTime time.Time) bool { p.RLock() defer p.RUnlock() entry, ok := p.perItemBackoff[id] if !ok { returnfalse } if p.hasExpired(eventTime, entry.lastUpdate, p.maxDuration) { returnfalse } return p.Clock.Since(eventTime) < entry.backoff }
// Returns True if time since lastupdate is less than the current backoff window. func(p *Backoff) IsInBackOffSinceUpdate(id string, eventTime time.Time) bool { p.RLock() defer p.RUnlock() entry, ok := p.perItemBackoff[id] if !ok { returnfalse } if p.hasExpired(eventTime, entry.lastUpdate, p.maxDuration) { returnfalse } return eventTime.Sub(entry.lastUpdate) < entry.backoff }
hasExpired 检查当前到达延迟时间的上限,
默认的检查是,距离上次 backoff 时间超过 2 倍 cap
提供了一个自定义 HasExpiredFunc,可以自定义实现,目前没有接口可以传递参数…
// Unless an alternate function is provided, after 2*maxDuration we restart the backoff factor to the beginning func(p *Backoff) hasExpired(eventTime time.Time, lastUpdate time.Time, maxDuration time.Duration) bool { if p.HasExpiredFunc != nil { return p.HasExpiredFunc(eventTime, lastUpdate, maxDuration) } return eventTime.Sub(lastUpdate) > maxDuration*2// consider stable if it's ok for twice the maxDuration }
其他
Reset
将 key 从 map 中删除,实现重置key 的 backoff
// Reset forces clearing of all backoff data for a given key. func(p *Backoff) Reset(id string) { p.Lock() defer p.Unlock() delete(p.perItemBackoff, id) }
GC
定期清理已经过期的 Expired 对象。
// Garbage collect records that have aged past their expiration, which defaults // to 2*maxDuration (see hasExpired godoc). Backoff users are expected to invoke // this periodically. func(p *Backoff) GC() { p.Lock() defer p.Unlock() now := p.Clock.Now() for id, entry := range p.perItemBackoff { if p.hasExpired(now, entry.lastUpdate, p.maxDuration) { delete(p.perItemBackoff, id) } } }
Get
查询 key 的延迟时间(backoff)
// Get the current backoff Duration func(p *Backoff) Get(id string) time.Duration { p.RLock() defer p.RUnlock() var delay time.Duration entry, ok := p.perItemBackoff[id] if ok { delay = entry.backoff } return delay }