|
|
|
@ -9,8 +9,13 @@ import ( |
|
|
|
|
|
|
|
|
|
"github.com/grafana/grafana/pkg/infra/log" |
|
|
|
|
"github.com/grafana/grafana/pkg/services/ngalert/metrics" |
|
|
|
|
"github.com/grafana/grafana/pkg/services/ngalert/models" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
type AlertInstancesProvider interface { |
|
|
|
|
GetAlertInstances(skipNormalState bool) []models.AlertInstance |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
type AsyncStatePersister struct { |
|
|
|
|
log log.Logger |
|
|
|
|
// doNotSaveNormalState controls whether eval.Normal state is persisted to the database and returned by get methods.
|
|
|
|
@ -30,16 +35,16 @@ func NewAsyncStatePersister(log log.Logger, ticker *clock.Ticker, cfg ManagerCfg |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (a *AsyncStatePersister) Async(ctx context.Context, cache *cache) { |
|
|
|
|
func (a *AsyncStatePersister) Async(ctx context.Context, instancesProvider AlertInstancesProvider) { |
|
|
|
|
for { |
|
|
|
|
select { |
|
|
|
|
case <-a.ticker.C: |
|
|
|
|
if err := a.fullSync(ctx, cache); err != nil { |
|
|
|
|
if err := a.fullSync(ctx, instancesProvider); err != nil { |
|
|
|
|
a.log.Error("Failed to do a full state sync to database", "err", err) |
|
|
|
|
} |
|
|
|
|
case <-ctx.Done(): |
|
|
|
|
a.log.Info("Scheduler is shutting down, doing a final state sync.") |
|
|
|
|
if err := a.fullSync(context.Background(), cache); err != nil { |
|
|
|
|
if err := a.fullSync(context.Background(), instancesProvider); err != nil { |
|
|
|
|
a.log.Error("Failed to do a full state sync to database", "err", err) |
|
|
|
|
} |
|
|
|
|
a.ticker.Stop() |
|
|
|
@ -49,10 +54,10 @@ func (a *AsyncStatePersister) Async(ctx context.Context, cache *cache) { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (a *AsyncStatePersister) fullSync(ctx context.Context, cache *cache) error { |
|
|
|
|
func (a *AsyncStatePersister) fullSync(ctx context.Context, instancesProvider AlertInstancesProvider) error { |
|
|
|
|
startTime := time.Now() |
|
|
|
|
a.log.Debug("Full state sync start") |
|
|
|
|
instances := cache.asInstances(a.doNotSaveNormalState) |
|
|
|
|
instances := instancesProvider.GetAlertInstances(a.doNotSaveNormalState) |
|
|
|
|
if err := a.store.FullSync(ctx, instances); err != nil { |
|
|
|
|
a.log.Error("Full state sync failed", "duration", time.Since(startTime), "instances", len(instances)) |
|
|
|
|
return err |
|
|
|
@ -64,6 +69,6 @@ func (a *AsyncStatePersister) fullSync(ctx context.Context, cache *cache) error |
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (a *AsyncStatePersister) Sync(_ context.Context, _ trace.Span, _ StateTransitions) { |
|
|
|
|
func (a *AsyncStatePersister) Sync(_ context.Context, _ trace.Span, _ models.AlertRuleKeyWithGroup, _ StateTransitions) { |
|
|
|
|
a.log.Debug("Sync: No-Op") |
|
|
|
|
} |
|
|
|
|