@@ -11,6 +11,7 @@ import (
1111 . "github.com/onsi/ginkgo/v2"
1212 . "github.com/onsi/gomega"
1313 "k8s.io/apimachinery/pkg/util/sets"
14+ "k8s.io/client-go/util/workqueue"
1415)
1516
1617var _ = Describe ("Controllerworkqueue" , func () {
@@ -438,6 +439,72 @@ var _ = Describe("Controllerworkqueue", func() {
438439 Expect (metrics .depth ["test" ]).To (Equal (0 ))
439440 metrics .mu .Unlock ()
440441 })
442+
443+ It ("When adding items with rateLimit, previous items' rateLimit should not affect subsequent items" , func () {
444+ q , metrics := newQueue ()
445+ defer q .ShutDown ()
446+
447+ now := time .Now ().Round (time .Second )
448+ nowLock := sync.Mutex {}
449+ tick := make (chan time.Time )
450+
451+ cwq := q .(* priorityqueue [string ])
452+ cwq .rateLimiter = workqueue .NewTypedItemExponentialFailureRateLimiter [string ](5 * time .Millisecond , 1000 * time .Second )
453+ cwq .now = func () time.Time {
454+ nowLock .Lock ()
455+ defer nowLock .Unlock ()
456+ return now
457+ }
458+ cwq .tick = func (d time.Duration ) <- chan time.Time {
459+ done := make (chan struct {})
460+ go func () {
461+ defer GinkgoRecover ()
462+ defer close (done )
463+
464+ Expect (d ).To (Or (Equal (5 * time .Millisecond ), Equal (635 * time .Millisecond )))
465+ }()
466+ <- done
467+ return tick
468+ }
469+
470+ retrievedItem := make (chan struct {})
471+ retrievedSecondItem := make (chan struct {})
472+
473+ go func () {
474+ defer GinkgoRecover ()
475+ first , _ , _ := q .GetWithPriority ()
476+ Expect (first ).To (Equal ("foo" ))
477+ close (retrievedItem )
478+
479+ second , _ , _ := q .GetWithPriority ()
480+ Expect (second ).To (Equal ("bar" ))
481+ close (retrievedSecondItem )
482+ }()
483+
484+ // after 7 calls, the next When("bar") call will return 640ms.
485+ for range 7 {
486+ cwq .rateLimiter .When ("bar" )
487+ }
488+ q .AddWithOpts (AddOpts {RateLimited : true }, "foo" , "bar" )
489+
490+ Consistently (retrievedItem ).ShouldNot (BeClosed ())
491+ nowLock .Lock ()
492+ now = now .Add (5 * time .Millisecond )
493+ nowLock .Unlock ()
494+ tick <- now
495+ Eventually (retrievedItem ).Should (BeClosed ())
496+
497+ Consistently (retrievedSecondItem ).ShouldNot (BeClosed ())
498+ nowLock .Lock ()
499+ now = now .Add (635 * time .Millisecond )
500+ nowLock .Unlock ()
501+ tick <- now
502+ Eventually (retrievedSecondItem ).Should (BeClosed ())
503+
504+ Expect (metrics .depth ["test" ]).To (Equal (0 ))
505+ Expect (metrics .adds ["test" ]).To (Equal (2 ))
506+ Expect (metrics .retries ["test" ]).To (Equal (2 ))
507+ })
441508})
442509
443510func BenchmarkAddGetDone (b * testing.B ) {
0 commit comments