snapshot of https://github.com/centrifugal/centrifugo.git (master, 2026-09-16; blobs > 131072B omitted)
Some checks failed
test / Lint (push) Failing after 3s
test / Test with Go 1.26.8 (push) Failing after 2s

This commit is contained in:
upstream-mirror
2026-09-16 01:17:21 +05:00
commit b352a9a30d
472 changed files with 108375 additions and 0 deletions

View File

@@ -0,0 +1,35 @@
package tools
import (
"sync/atomic"
"time"
)
// IntervalLimiter permits an action at most once per configured interval. It is
// safe for concurrent use and does no allocation or locking on the hot path -
// just an atomic load (and a single CAS when the action is actually allowed),
// so guarding a rare log line with it is effectively free when the interval has
// not elapsed.
type IntervalLimiter struct {
intervalNanos int64
lastNanos atomic.Int64
}
// NewIntervalLimiter creates an IntervalLimiter that allows an action at most
// once per interval.
func NewIntervalLimiter(interval time.Duration) *IntervalLimiter {
return &IntervalLimiter{intervalNanos: int64(interval)}
}
// Allow reports whether the action may run now. Across all concurrent callers it
// returns true at most once per interval. The first call always returns true.
func (l *IntervalLimiter) Allow() bool {
now := time.Now().UnixNano()
last := l.lastNanos.Load()
if now-last < l.intervalNanos {
return false
}
// Only the caller that swaps in the new timestamp is allowed to proceed, so
// concurrent callers in the same window can't all log.
return l.lastNanos.CompareAndSwap(last, now)
}