package limiter import ( "sync" "time" ) type Limiter interface { Wait() } type limiter struct { tick time.Duration count int entries []time.Time index int mutex sync.Mutex } func NewLimiter(tick time.Duration, count int) Limiter { l := limiter{ tick: tick, count: count, entries: make([]time.Time, count), index: 0, } 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 } }