add a blocking accept method to RateLimiter

This commit is contained in:
Ben Parees 2015-04-01 17:57:30 -04:00
parent 0cf3590c36
commit 70be667cf8
3 changed files with 22 additions and 0 deletions

View File

@ -32,6 +32,7 @@ type fakeRL bool
func (fakeRL) Stop() {}
func (f fakeRL) CanAccept() bool { return bool(f) }
func (f fakeRL) Accept() {}
func TestRateLimit(t *testing.T) {
for _, allow := range []bool{true, false} {

View File

@ -24,6 +24,8 @@ import (
type RateLimiter interface {
// CanAccept returns true if the rate is below the limit, false otherwise
CanAccept() bool
// Accept returns once a token becomes available.
Accept()
// Stop stops the rate limiter, subsequent calls to CanAccept will return false
Stop()
}
@ -73,6 +75,11 @@ func (t *tickRateLimiter) CanAccept() bool {
}
}
// Accept will block until a token becomes available
func (t *tickRateLimiter) Accept() {
<-t.tokens
}
func (t *tickRateLimiter) Stop() {
close(t.stop)
}

View File

@ -60,3 +60,17 @@ func TestOverBurst(t *testing.T) {
r.step()
}
}
func TestThrottle(t *testing.T) {
r := NewTokenBucketRateLimiter(10, 5)
// Should consume 5 tokens immediately, then
// the remaining 11 should take at least 1 second (0.1s each)
expectedFinish := time.Now().Add(time.Second * 1)
for i := 0; i < 16; i++ {
r.Accept()
}
if time.Now().Before(expectedFinish) {
t.Error("rate limit was not respected, finished too early")
}
}