mirror of
https://github.com/hackdiaz-dev/free-turn-proxy.git
synced 2026-10-12 09:41:53 +02:00
53 lines
1.1 KiB
Go
53 lines
1.1 KiB
Go
// Package allocpace распределяет во времени вызовы TURN Allocate: квота считается на
|
|
// username, поэтому залп от всех потоков сразу упирается в неё плотнее, чем очередь.
|
|
package allocpace
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
const DefaultInterval = 200 * time.Millisecond
|
|
|
|
type Pacer struct {
|
|
mu sync.Mutex
|
|
next time.Time
|
|
step time.Duration
|
|
}
|
|
|
|
func New(step time.Duration) *Pacer {
|
|
return &Pacer{step: step}
|
|
}
|
|
|
|
// Wait возвращает false, только если ctx отменён - слот всё равно занят и не переиспользуется.
|
|
func (p *Pacer) Wait(ctx context.Context) bool {
|
|
if p == nil {
|
|
return ctx.Err() == nil
|
|
}
|
|
wait := time.Until(p.slot())
|
|
if wait <= 0 {
|
|
return ctx.Err() == nil
|
|
}
|
|
t := time.NewTimer(wait)
|
|
defer t.Stop()
|
|
select {
|
|
case <-t.C:
|
|
return true
|
|
case <-ctx.Done():
|
|
return false
|
|
}
|
|
}
|
|
|
|
func (p *Pacer) slot() time.Time {
|
|
p.mu.Lock()
|
|
defer p.mu.Unlock()
|
|
now := time.Now()
|
|
if p.next.Before(now) {
|
|
p.next = now
|
|
}
|
|
slot := p.next
|
|
p.next = slot.Add(p.step)
|
|
return slot
|
|
}
|