@@ -3,6 +3,7 @@ package fast_retry
33import (
44 "context"
55 "errors"
6+ "fmt"
67 "log"
78 "math/rand"
89 "os"
@@ -188,6 +189,71 @@ func TestMaxRetryRate(t *testing.T) {
188189 require .True (t , callbackCnt .Load () < int64 (float64 (successCnt .Load ())* 1.2 ))
189190}
190191
192+ func TestMaxRetryCapacity (t * testing.T ) {
193+ if testing .Short () {
194+ t .Skip ()
195+ }
196+ ctx := context .Background ()
197+ var callbackCnt atomic.Int64
198+ var errorCnt atomic.Int64
199+ var successCnt atomic.Int64
200+ // 模拟 FastRetryTime 设置不当,看请求是否放大两次
201+ maxRetryCapacity := 100
202+ r := New (Config {MaxRetryRate : 0.1 , FastRetryTime : time .Second / 15 , MaxRetryCapacity : maxRetryCapacity })
203+ slow := false
204+ fn := func () (resp interface {}, err error ) {
205+ callbackCnt .Inc ()
206+ if slow {
207+ time .Sleep (time .Second / 10 )
208+ }
209+ return "ok" , nil
210+ }
211+ {
212+ g , ctx := errgroup .WithContext (ctx )
213+ for i := 0 ; i < 100 ; i ++ {
214+ g .Go (func () error {
215+ for j := 0 ; j < 100 ; j ++ {
216+ _ , err := r .BackupRetry (ctx , fn )
217+ if err != nil {
218+ fmt .Println (err )
219+ errorCnt .Inc ()
220+ } else {
221+ successCnt .Inc ()
222+ }
223+ }
224+ return nil
225+ })
226+ }
227+ _ = g .Wait ()
228+ }
229+
230+ slow = true
231+ {
232+ g , ctx := errgroup .WithContext (ctx )
233+ for i := 0 ; i < 50 ; i ++ {
234+ g .Go (func () error {
235+ for j := 0 ; j < 100 ; j ++ {
236+ _ , err := r .BackupRetry (ctx , fn )
237+ if err != nil {
238+ fmt .Println (err )
239+ errorCnt .Inc ()
240+ } else {
241+ successCnt .Inc ()
242+ }
243+ }
244+ return nil
245+ })
246+ }
247+ _ = g .Wait ()
248+ }
249+ // 先 10000 个快速请求,然后 5000 个慢请求
250+ // 5000 里面会有 10% 被重试,之前 10000 会积累一部分 quota
251+ t .Logf ("%v %v %v" , callbackCnt .Load (), errorCnt .Load (), successCnt .Load ())
252+ require .Equal (t , errorCnt .Load (), int64 (0 ))
253+ require .True (t , callbackCnt .Load () < int64 (float64 (successCnt .Load ())* 1.2 ))
254+ require .True (t , callbackCnt .Load () <= int64 (10000 + 5000 + 5000 * 0.1 + maxRetryCapacity * 2 ))
255+ }
256+
191257func BenchmarkRetry (b * testing.B ) {
192258 ctx := context .Background ()
193259 r := New (Config {MaxRetryRate : 0.1 , FastRetryTime : time .Second / 100 })
0 commit comments