diff --git a/dispatch.go b/dispatch.go index 9dc8483b..dae4408f 100644 --- a/dispatch.go +++ b/dispatch.go @@ -197,16 +197,22 @@ func (ag *aggrGroup) run(nf notifyFunc) { defer close(ag.done) defer ag.next.Stop() + timeout := ag.opts.GroupInterval + + if timeout < notify.MinTimeout { + timeout = notify.MinTimeout + } + for { select { case now := <-ag.next.C: // Give the notifcations time until the next flush to // finish before terminating them. - ctx, _ := context.WithTimeout(ag.ctx, ag.opts.GroupInterval) + ctx, cancel := context.WithTimeout(ag.ctx, timeout) // The now time we retrieve from the ticker is the only reliable // point of time reference for the subsequent notification pipeline. - // Calculating the current time directly is prone to avoid flaky behavior, + // Calculating the current time directly is prone to flaky behavior, // which usually only becomes apparent in tests. ctx = notify.WithNow(ctx, now) @@ -223,6 +229,8 @@ func (ag *aggrGroup) run(nf notifyFunc) { return nf(ctx, alerts...) }) + cancel() + case <-ag.ctx.Done(): return } diff --git a/notify/notify.go b/notify/notify.go index 4db4e0df..cf3aa7a9 100644 --- a/notify/notify.go +++ b/notify/notify.go @@ -14,6 +14,10 @@ import ( "github.com/prometheus/alertmanager/types" ) +// The minimum timeout that is set for the context of a call +// to a notification pipeline. +const MinTimeout = 10 * time.Second + type notifyKey int const (