package limiter import ( "context" "sync" "time" ) type RateLimiter struct { requests chan struct{} done chan struct{} maxRequests int Interval time.Duration mutex sync.Mutex } func NewRateLimiter(ctx context.Context, maxRequests int, interval time.Duration) *RateLimiter { limiter := &RateLimiter{ requests: make(chan struct{}, maxRequests), done: make(chan struct{}), maxRequests: maxRequests, Interval: interval, } go limiter.start(ctx) return limiter } func (limiter *RateLimiter) start(ctx context.Context) { ticker := time.NewTicker(limiter.Interval) defer ticker.Stop() for { select { case <-ticker.C: limiter.mutex.Lock() for i := 0; i < len(limiter.requests); i++ { <-limiter.requests } limiter.mutex.Unlock() case <-ctx.Done(): return } } } func (limiter *RateLimiter) Check() bool { select { case limiter.requests <- struct{}{}: return true default: return false } } func (limiter *RateLimiter) Stop(_ context.Context) error { return nil }