1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-06-28 15:27:43 +00:00
FrankerFaceZ/socketserver/server/rate/ratelimit.go

78 lines
1.6 KiB
Go
Raw Permalink Normal View History

package rate
2017-02-02 22:59:17 -08:00
import (
"io"
2017-02-02 23:08:21 -08:00
"time"
2017-02-02 22:59:17 -08:00
)
// A Limiter supports a constant number of Performed() calls every
// time a certain amount of time passes.
2017-02-02 22:59:17 -08:00
//
// Calls to Performed() when no "action tokens" are available will block
// until one is available.
type Limiter interface {
2017-02-02 22:59:17 -08:00
// Run begins emitting tokens for the ratelimiter.
// A call to Run must be followed by a call to Close.
Run()
// Performed consumes one token from the rate limiter.
// If no tokens are available, the call will block until one is.
Performed()
// Close stops the rate limiter. Any future calls to Performed() will block forever.
// Close never returns an error.
io.Closer
}
2017-02-02 23:08:21 -08:00
type timeRateLimit struct {
2017-02-02 22:59:17 -08:00
count int
period time.Duration
ch chan struct{}
done chan struct{}
}
// Construct a new Limiter with the given count and duration.
func NewRateLimit(count int, period time.Duration) Limiter {
2017-02-02 22:59:17 -08:00
return &timeRateLimit{
count: count,
period: period,
ch: make(chan struct{}),
done: make(chan struct{}),
}
}
func (r *timeRateLimit) Run() {
for {
waiter := time.After(r.period)
for i := 0; i < r.count; i++ {
select {
case r.ch <- struct{}{}:
// ok
case <-r.done:
return
}
}
<-waiter
}
}
func (r *timeRateLimit) Performed() {
<-r.ch
}
func (r *timeRateLimit) Close() error {
close(r.done)
return nil
}
type unlimited struct{}
2017-02-02 23:08:21 -08:00
2017-02-02 22:59:17 -08:00
var unlimitedInstance unlimited
// Unlimited returns a Limiter that never blocks. The Run() and Close() calls are no-ops.
func Unlimited() Limiter {
2017-02-02 22:59:17 -08:00
return unlimitedInstance
}
2017-02-02 23:08:21 -08:00
func (r unlimited) Run() {}
func (r unlimited) Performed() {}
2017-02-02 22:59:17 -08:00
func (r unlimited) Close() error { return nil }