Alerting: Start ticker only when scheduler starts (#56339)

This commit is contained in:
Yuriy Tseretyan
2022-10-05 09:35:02 -04:00
committed by GitHub
parent 8594e648e8
commit ad2a1dd680

View File

@@ -40,7 +40,6 @@ type ScheduleService interface {
// the following are used by tests only used for tests // the following are used by tests only used for tests
evalApplied(ngmodels.AlertRuleKey, time.Time) evalApplied(ngmodels.AlertRuleKey, time.Time)
stopApplied(ngmodels.AlertRuleKey) stopApplied(ngmodels.AlertRuleKey)
overrideCfg(cfg SchedulerCfg)
} }
// AlertsSender is an interface for a service that is responsible for sending notifications to the end-user. // AlertsSender is an interface for a service that is responsible for sending notifications to the end-user.
@@ -67,8 +66,6 @@ type schedule struct {
clock clock.Clock clock clock.Clock
ticker *ticker.T
// evalApplied is only used for tests: test code can set it to non-nil // evalApplied is only used for tests: test code can set it to non-nil
// function, and then it'll be called from the event loop whenever the // function, and then it'll be called from the event loop whenever the
// message from evalApplied is handled. // message from evalApplied is handled.
@@ -117,15 +114,12 @@ type SchedulerCfg struct {
// NewScheduler returns a new schedule. // NewScheduler returns a new schedule.
func NewScheduler(cfg SchedulerCfg, appURL *url.URL, stateManager *state.Manager) *schedule { func NewScheduler(cfg SchedulerCfg, appURL *url.URL, stateManager *state.Manager) *schedule {
ticker := ticker.New(cfg.C, cfg.Cfg.BaseInterval, cfg.Metrics.Ticker)
sch := schedule{ sch := schedule{
registry: alertRuleInfoRegistry{alertRuleInfo: make(map[ngmodels.AlertRuleKey]*alertRuleInfo)}, registry: alertRuleInfoRegistry{alertRuleInfo: make(map[ngmodels.AlertRuleKey]*alertRuleInfo)},
maxAttempts: cfg.Cfg.MaxAttempts, maxAttempts: cfg.Cfg.MaxAttempts,
clock: cfg.C, clock: cfg.C,
baseInterval: cfg.Cfg.BaseInterval, baseInterval: cfg.Cfg.BaseInterval,
log: cfg.Logger, log: cfg.Logger,
ticker: ticker,
evalAppliedFunc: cfg.EvalAppliedFunc, evalAppliedFunc: cfg.EvalAppliedFunc,
stopAppliedFunc: cfg.StopAppliedFunc, stopAppliedFunc: cfg.StopAppliedFunc,
evaluator: cfg.Evaluator, evaluator: cfg.Evaluator,
@@ -143,9 +137,10 @@ func NewScheduler(cfg SchedulerCfg, appURL *url.URL, stateManager *state.Manager
} }
func (sch *schedule) Run(ctx context.Context) error { func (sch *schedule) Run(ctx context.Context) error {
defer sch.ticker.Stop() t := ticker.New(sch.clock, sch.baseInterval, sch.metrics.Ticker)
defer t.Stop()
if err := sch.schedulePeriodic(ctx); err != nil { if err := sch.schedulePeriodic(ctx, t); err != nil {
sch.log.Error("failure while running the rule evaluation loop", "err", err) sch.log.Error("failure while running the rule evaluation loop", "err", err)
} }
return nil return nil
@@ -184,11 +179,11 @@ func (sch *schedule) DeleteAlertRule(keys ...ngmodels.AlertRuleKey) {
sch.metrics.SchedulableAlertRulesHash.Set(float64(hashUIDs(alertRules))) sch.metrics.SchedulableAlertRulesHash.Set(float64(hashUIDs(alertRules)))
} }
func (sch *schedule) schedulePeriodic(ctx context.Context) error { func (sch *schedule) schedulePeriodic(ctx context.Context, t *ticker.T) error {
dispatcherGroup, ctx := errgroup.WithContext(ctx) dispatcherGroup, ctx := errgroup.WithContext(ctx)
for { for {
select { select {
case tick := <-sch.ticker.C: case tick := <-t.C:
// We use Round(0) on the start time to remove the monotonic clock. // We use Round(0) on the start time to remove the monotonic clock.
// This is required as ticks from the ticker and time.Now() can have // This is required as ticks from the ticker and time.Now() can have
// a monotonic clock that when subtracted do not represent the delta // a monotonic clock that when subtracted do not represent the delta
@@ -442,16 +437,6 @@ func (sch *schedule) ruleRoutine(grafanaCtx context.Context, key ngmodels.AlertR
} }
} }
// overrideCfg is only used on tests.
func (sch *schedule) overrideCfg(cfg SchedulerCfg) {
sch.clock = cfg.C
sch.baseInterval = cfg.Cfg.BaseInterval
sch.ticker.Stop()
sch.ticker = ticker.New(cfg.C, cfg.Cfg.BaseInterval, cfg.Metrics.Ticker)
sch.evalAppliedFunc = cfg.EvalAppliedFunc
sch.stopAppliedFunc = cfg.StopAppliedFunc
}
// evalApplied is only used on tests. // evalApplied is only used on tests.
func (sch *schedule) evalApplied(alertDefKey ngmodels.AlertRuleKey, now time.Time) { func (sch *schedule) evalApplied(alertDefKey ngmodels.AlertRuleKey, now time.Time) {
if sch.evalAppliedFunc == nil { if sch.evalAppliedFunc == nil {