converge/pkg/support/throttling/throttler.go

46 lines
1.4 KiB
Go

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)
}
}