diff --git a/pkg/common/sync_subject.go b/pkg/common/sync_subject.go index f166b63b..a39d6df6 100644 --- a/pkg/common/sync_subject.go +++ b/pkg/common/sync_subject.go @@ -2,6 +2,7 @@ package common import ( "github.com/icinga/icingadb/pkg/contracts" + v1 "github.com/icinga/icingadb/pkg/icingadb/v1" "github.com/icinga/icingadb/pkg/utils" ) @@ -47,6 +48,18 @@ func (s SyncSubject) Factory() contracts.EntityFactoryFunc { return s.factory } +// FactoryForDelta behaves like Factory() unless s is WithChecksum(). +// In the latter case it returns a factory for EntityWithChecksum instead. +// Rationale: Sync#ApplyDelta() uses its input entities which are WithChecksum() only for the delta itself +// and not for insertion into the database, so EntityWithChecksum is enough. And it consumes less memory. +func (s SyncSubject) FactoryForDelta() contracts.EntityFactoryFunc { + if s.withChecksum { + return v1.NewEntityWithChecksum + } + + return s.factory +} + // Name returns the declared name of the entity. func (s SyncSubject) Name() string { return utils.Name(s.entity) diff --git a/pkg/icingadb/sync.go b/pkg/icingadb/sync.go index 9af78e86..790f11e4 100644 --- a/pkg/icingadb/sync.go +++ b/pkg/icingadb/sync.go @@ -84,7 +84,9 @@ func (s Sync) Sync(ctx context.Context, subject *common.SyncSubject) error { } actual, dbErrs := s.db.YieldAll( - ctx, subject.Factory(), s.db.BuildSelectStmt(NewScopedEntity(subject.Entity(), e.Meta()), subject.Entity().Fingerprint()), e.Meta()) + ctx, subject.FactoryForDelta(), + s.db.BuildSelectStmt(NewScopedEntity(subject.Entity(), e.Meta()), subject.Entity().Fingerprint()), e.Meta(), + ) // Let errors from DB cancel our group. com.ErrgroupReceive(g, dbErrs) @@ -184,7 +186,9 @@ func (s Sync) SyncCustomvars(ctx context.Context) error { com.ErrgroupReceive(g, errs) actualCvs, errs := s.db.YieldAll( - ctx, cv.Factory(), s.db.BuildSelectStmt(NewScopedEntity(cv.Entity(), e.Meta()), cv.Entity().Fingerprint()), e.Meta()) + ctx, cv.FactoryForDelta(), + s.db.BuildSelectStmt(NewScopedEntity(cv.Entity(), e.Meta()), cv.Entity().Fingerprint()), e.Meta(), + ) com.ErrgroupReceive(g, errs) g.Go(func() error { @@ -194,7 +198,9 @@ func (s Sync) SyncCustomvars(ctx context.Context) error { flatCv := common.NewSyncSubject(v1.NewCustomvarFlat) actualFlatCvs, errs := s.db.YieldAll( - ctx, flatCv.Factory(), s.db.BuildSelectStmt(NewScopedEntity(flatCv.Entity(), e.Meta()), flatCv.Entity().Fingerprint()), e.Meta()) + ctx, flatCv.FactoryForDelta(), + s.db.BuildSelectStmt(NewScopedEntity(flatCv.Entity(), e.Meta()), flatCv.Entity().Fingerprint()), e.Meta(), + ) com.ErrgroupReceive(g, errs) g.Go(func() error { diff --git a/pkg/icingadb/v1/entity.go b/pkg/icingadb/v1/entity.go index 02e659e3..5dfa3d29 100644 --- a/pkg/icingadb/v1/entity.go +++ b/pkg/icingadb/v1/entity.go @@ -22,3 +22,7 @@ type EntityWithChecksum struct { func (e EntityWithChecksum) Fingerprint() contracts.Fingerprinter { return e } + +func NewEntityWithChecksum() contracts.Entity { + return &EntityWithChecksum{} +} diff --git a/pkg/icingaredis/client.go b/pkg/icingaredis/client.go index 040d9761..d42713c6 100644 --- a/pkg/icingaredis/client.go +++ b/pkg/icingaredis/client.go @@ -222,7 +222,7 @@ func (c Client) YieldAll(ctx context.Context, subject *common.SyncSubject) (<-ch // Let errors from HYield cancel the group. com.ErrgroupReceive(g, errs) - desired, errs := CreateEntities(ctx, subject.Factory(), pairs, runtime.NumCPU()) + desired, errs := CreateEntities(ctx, subject.FactoryForDelta(), pairs, runtime.NumCPU()) // Let errors from CreateEntities cancel the group. com.ErrgroupReceive(g, errs)