redis/rate_limit.go

53 lines
852 B
Go
Raw Normal View History

package redis
import (
2014-10-02 12:32:49 +04:00
"sync/atomic"
"time"
)
type rateLimiter struct {
2014-10-02 12:32:49 +04:00
v int64
_closed int64
}
2014-10-02 12:32:49 +04:00
func newRateLimiter(limit time.Duration, bucketSize int) *rateLimiter {
rl := &rateLimiter{
2014-10-02 12:32:49 +04:00
v: int64(bucketSize),
}
2014-10-02 12:32:49 +04:00
go rl.loop(limit, int64(bucketSize))
return rl
}
2014-10-02 12:32:49 +04:00
func (rl *rateLimiter) loop(limit time.Duration, bucketSize int64) {
for {
2014-10-02 12:32:49 +04:00
if rl.closed() {
break
}
if v := atomic.LoadInt64(&rl.v); v < bucketSize {
atomic.AddInt64(&rl.v, 1)
}
time.Sleep(limit)
}
}
2014-10-02 12:32:49 +04:00
func (rl *rateLimiter) Check() bool {
for {
if v := atomic.LoadInt64(&rl.v); v > 0 {
if atomic.CompareAndSwapInt64(&rl.v, v, v-1) {
return true
}
}
return false
}
}
func (rl *rateLimiter) Close() error {
atomic.StoreInt64(&rl._closed, 1)
return nil
}
func (rl *rateLimiter) closed() bool {
return atomic.LoadInt64(&rl._closed) == 1
}