package throttling import "time" // Throttling notifications to prometheus and web clients // TO be used in a single-threaded manner. type Throttler[T any] struct { minDelaySeconds float64 // ucntion to call to implement the notification. notifier func(t *T) lastReportedTime time.Time pendingValue *T } func NewThrottler[T any](notifier func(t *T), minDelaySeconds float64) Throttler[T] { throttler := Throttler[T]{ minDelaySeconds: minDelaySeconds, notifier: notifier, lastReportedTime: time.Time{}, pendingValue: nil, } return throttler } // Notify there is a new value. Performs notification if it was long enough ago // for the last notification to be sent. If not, it is stored as a pending event to // be sent later. New events that come in before a notification is sent override the // pending event. func (throttler *Throttler[T]) Notify(time time.Time, value *T) { if time.Sub(throttler.lastReportedTime).Seconds() >= throttler.minDelaySeconds { throttler.notifier(value) throttler.lastReportedTime = time throttler.pendingValue = nil return } throttler.pendingValue = value } // To be called periodically. It sends out any pending events if the time the last // notification was sent is long enough ago. func (throttler *Throttler[T]) Ping(time time.Time) { if throttler.pendingValue != nil { throttler.Notify(time, throttler.pendingValue) } }