typeRateLimiterinterface{// When gets an item and gets to decide how long that item should wait
//當一個物件放入的時候,需要回傳延遲多久(可自定義規則,等等會看到)
When(iteminterface{})time.Duration// Forget indicates that an item is finished being retried. Doesn't matter whether its for perm failing
// or for success, we'll stop tracking it
//當一個物件完成的時候可以,要忘記曾經延遲過(重新計算)
Forget(iteminterface{})// NumRequeues returns back how many failures the item has had
// 回傳物件已經放入幾次(重試了幾次,白話一點呼叫NumRequeues幾次)
NumRequeues(iteminterface{})int}
// ItemExponentialFailureRateLimiter does a simple baseDelay*2^<num-failures> limit
// dealing with max failures and expiration are up to the caller
typeItemExponentialFailureRateLimiterstruct{failuresLocksync.Mutex//鎖,防止資源競爭
failuresmap[interface{}]int//計算某個物件呼叫了延遲的次數
baseDelaytime.Duration//基礎延遲的時間
maxDelaytime.Duration//最多要延遲多久
}
func(r*ItemExponentialFailureRateLimiter)When(iteminterface{})time.Duration{r.failuresLock.Lock()//鎖不做解釋
deferr.failuresLock.Unlock()//解鎖不做解釋
exp:=r.failures[item]//查看map裡面物件放入的次數
r.failures[item]=r.failures[item]+1//放入次數+1
// The backoff is capped such that 'calculated' value never overflows.
// backoff=base * 2^(物件放入的次數),代表延遲時間為指數型成長。
backoff:=float64(r.baseDelay.Nanoseconds())*math.Pow(2,float64(exp))//如果backoff 大於int64(溢位)就回傳最大延遲時間
ifbackoff>math.MaxInt64{returnr.maxDelay}//封裝為延遲時間
calculated:=time.Duration(backoff)//延遲時間超過最大延遲時間就回傳最大延遲時間
ifcalculated>r.maxDelay{returnr.maxDelay}returncalculated}
NumRequeues
當我們需要知道物件已經重試了幾次可以透過NumRequeues function 得知物件重是的次數。 source code
funcNewRateLimitingQueue(rateLimiterRateLimiter)RateLimitingInterface{return&rateLimitingType{DelayingInterface:NewDelayingQueue(),//前一小節有提到過delating work queue的newfunction
rateLimiter:rateLimiter,//自行實作的rateLimiter
}}