2022-05-31 11:49:07 -04:00
|
|
|
package limiter
|
|
|
|
|
|
|
|
import (
|
|
|
|
"sync"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Limiter interface {
|
|
|
|
Wait()
|
|
|
|
}
|
|
|
|
|
|
|
|
type limiter struct {
|
|
|
|
tick time.Duration
|
2022-06-02 02:09:59 -04:00
|
|
|
count int
|
2022-05-31 11:49:07 -04:00
|
|
|
entries []time.Time
|
2022-06-02 02:09:59 -04:00
|
|
|
index int
|
2022-05-31 11:49:07 -04:00
|
|
|
mutex sync.Mutex
|
|
|
|
}
|
|
|
|
|
2022-06-02 02:09:59 -04:00
|
|
|
func NewLimiter(tick time.Duration, count int) Limiter {
|
2022-05-31 11:49:07 -04:00
|
|
|
l := limiter{
|
2022-06-02 02:09:59 -04:00
|
|
|
tick: tick,
|
|
|
|
count: count,
|
|
|
|
entries: make([]time.Time, count),
|
|
|
|
index: 0,
|
2022-05-31 11:49:07 -04:00
|
|
|
}
|
|
|
|
return &l
|
|
|
|
}
|
|
|
|
func (l *limiter) Wait() {
|
|
|
|
l.mutex.Lock()
|
|
|
|
defer l.mutex.Unlock()
|
|
|
|
last := &l.entries[l.index]
|
|
|
|
next := last.Add(l.tick)
|
|
|
|
now := time.Now()
|
|
|
|
if now.Before(next) {
|
|
|
|
time.Sleep(next.Sub(now))
|
|
|
|
}
|
|
|
|
*last = time.Now()
|
|
|
|
l.index = l.index + 1
|
|
|
|
if l.index == l.count {
|
|
|
|
l.index = 0
|
|
|
|
}
|
|
|
|
}
|