amocrm/internal/workers/limiter/limiter.go
2024-05-06 23:35:08 +03:00

59 lines
1.0 KiB
Go

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
}