package throttling import ( "context" "time" ) type AsyncThrottler[T any] struct { throttler Throttler[T] ctx context.Context cancel context.CancelFunc events chan *T ticker *time.Ticker } func NewAsyncThrottler[T any](notifier func(t *T), minDelay time.Duration, pollInterval time.Duration) *AsyncThrottler[T] { ctx, cancel := context.WithCancel(context.Background()) throttler := AsyncThrottler[T]{ throttler: NewThrottler[T](notifier, minDelay), ctx: ctx, cancel: cancel, events: make(chan *T), ticker: time.NewTicker(pollInterval), } go func() { for { select { case <-ctx.Done(): return case <-throttler.ticker.C: throttler.throttler.Ping() case event := <-throttler.events: throttler.throttler.Notify(event) } } }() return &throttler } func (throttler *AsyncThrottler[T]) Notify(value *T) { throttler.events <- value } func (throttler *AsyncThrottler[T]) Stop() { throttler.cancel() throttler.ticker.Stop() }