mirror of
https://git.sr.ht/~joren/streamrip-go
synced 2026-06-17 15:05:39 +02:00
initial Go port of streamrip
This commit is contained in:
54
internal/ratelimit/limiter.go
Normal file
54
internal/ratelimit/limiter.go
Normal file
@@ -0,0 +1,54 @@
|
||||
package ratelimit
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Limiter struct {
|
||||
interval time.Duration
|
||||
|
||||
mu sync.Mutex
|
||||
next time.Time
|
||||
}
|
||||
|
||||
func New(requestsPerMinute int) *Limiter {
|
||||
if requestsPerMinute <= 0 {
|
||||
return &Limiter{}
|
||||
}
|
||||
return &Limiter{interval: time.Minute / time.Duration(requestsPerMinute)}
|
||||
}
|
||||
|
||||
func (l *Limiter) Wait(ctx context.Context) error {
|
||||
if l.interval <= 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
l.mu.Lock()
|
||||
now := time.Now()
|
||||
if l.next.IsZero() {
|
||||
l.next = now.Add(l.interval)
|
||||
l.mu.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
wake := l.next
|
||||
if now.After(wake) {
|
||||
l.next = now.Add(l.interval)
|
||||
l.mu.Unlock()
|
||||
return nil
|
||||
}
|
||||
l.next = l.next.Add(l.interval)
|
||||
l.mu.Unlock()
|
||||
|
||||
timer := time.NewTimer(time.Until(wake))
|
||||
defer timer.Stop()
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case <-timer.C:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user