more problems since state is immutable but some state of agents and
client is not immutable so it ignored events that were not really
duplicates.
This reverts commit f6b0211336.
48 lines
1.3 KiB
Go
48 lines
1.3 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 {
|
|
minDelay time.Duration
|
|
// ucntion to call to implement the notification.
|
|
notifier func(t *T)
|
|
lastReportedTime time.Time
|
|
pendingValue *T
|
|
}
|
|
|
|
func NewThrottler[T any](notifier func(t *T), minDelay time.Duration) Throttler[T] {
|
|
throttler := Throttler[T]{
|
|
minDelay: minDelay,
|
|
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(value *T) {
|
|
if clock.time().Sub(throttler.lastReportedTime) >= throttler.minDelay {
|
|
throttler.notifier(value)
|
|
throttler.lastReportedTime = clock.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() {
|
|
if throttler.pendingValue != nil {
|
|
throttler.Notify(throttler.pendingValue)
|
|
}
|
|
}
|