Skip to content

Commit d286bb5

Browse files
authored
Merge pull request kubernetes-sigs#859 from alexeldeib/ace/limiter
🐛 fix conservative delay in rate limiter
2 parents edf7177 + 843039b commit d286bb5

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

pkg/client/apiutil/dynamicrestmapper.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,5 +318,6 @@ func (b *dynamicLimiter) checkRate() error {
318318
if res.Delay() == 0 {
319319
return nil
320320
}
321+
res.Cancel()
321322
return ErrRateLimited{res.Delay()}
322323
}

pkg/client/apiutil/dynamicrestmapper_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,26 @@ var _ = Describe("Dynamic REST Mapper", func() {
8686
}, "10s").Should(BeTrue())
8787
})
8888

89+
It("should rate-limit then allow more at 1rps", func() {
90+
By("setting a small limit")
91+
*lim = *rate.NewLimiter(rate.Limit(1), 1)
92+
93+
By("forcing a reload after changing the mapper")
94+
addToMapper = func(baseMapper *meta.DefaultRESTMapper) {
95+
baseMapper.Add(secondGVK, meta.RESTScopeNamespace)
96+
}
97+
98+
By("calling twice to trigger rate limiting")
99+
Expect(callWithOther()).To(Succeed())
100+
Expect(callWithTarget()).NotTo(Succeed())
101+
102+
// by 2nd call loop should succeed because we canceled our 1st rate-limited token, then waited a full second
103+
By("calling until no longer rate-limited, 2nd call should succeed")
104+
Eventually(func() bool {
105+
return errors.As(callWithTarget(), &apiutil.ErrRateLimited{})
106+
}, "2.5s", "1s").Should(BeFalse())
107+
})
108+
89109
It("should avoid reloading twice if two requests for the same thing come in", func() {
90110
count := 0
91111
// we use sleeps here to simulate two simulataneous requests by slowing things down

0 commit comments

Comments
 (0)