mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-12-26 20:30:10 +01:00
b8369e2f3e
The new flag `vm-rate-limit` defines data transfer speed limit in bytes per second. Rate limiting is not applied if flag is omitted. https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1405 Signed-off-by: hagen1778 <roman@victoriametrics.com>
54 lines
1.1 KiB
Go
54 lines
1.1 KiB
Go
package limiter
|
|
|
|
import (
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/timerpool"
|
|
)
|
|
|
|
// NewLimiter creates a Limiter object
|
|
// for the given perSecondLimit
|
|
func NewLimiter(perSecondLimit int64) *Limiter {
|
|
return &Limiter{perSecondLimit: perSecondLimit}
|
|
}
|
|
|
|
// Limiter controls the amount of budget
|
|
// that can be spent according to configured perSecondLimit
|
|
type Limiter struct {
|
|
perSecondLimit int64
|
|
|
|
// mu protects budget and deadline from concurrent access.
|
|
mu sync.Mutex
|
|
|
|
// The current budget. It is increased by perSecondLimit every second.
|
|
budget int64
|
|
|
|
// The next deadline for increasing the budget by perSecondLimit
|
|
deadline time.Time
|
|
}
|
|
|
|
// Register blocks for amount of time
|
|
// needed to process the given dataLen according
|
|
// to the configured perSecondLimit.
|
|
func (l *Limiter) Register(dataLen int) {
|
|
limit := l.perSecondLimit
|
|
if limit <= 0 {
|
|
return
|
|
}
|
|
|
|
l.mu.Lock()
|
|
defer l.mu.Unlock()
|
|
|
|
for l.budget <= 0 {
|
|
if d := time.Until(l.deadline); d > 0 {
|
|
t := timerpool.Get(d)
|
|
<-t.C
|
|
timerpool.Put(t)
|
|
}
|
|
l.budget += limit
|
|
l.deadline = time.Now().Add(time.Second)
|
|
}
|
|
l.budget -= int64(dataLen)
|
|
}
|