Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 19 additions & 21 deletions central/administration/events/handler/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ package handler

import (
"context"
"time"

"github.com/stackrox/rox/central/administration/events/datastore"
"github.com/stackrox/rox/generated/storage"
"github.com/stackrox/rox/pkg/administration/events"
"github.com/stackrox/rox/pkg/backgroundworker"
"github.com/stackrox/rox/pkg/concurrency"
"github.com/stackrox/rox/pkg/env"
"github.com/stackrox/rox/pkg/logging"
Expand All @@ -33,6 +33,8 @@ type handlerImpl struct {
eventWriteCtx context.Context
stream events.Stream
stopSignal concurrency.Signal

flushWorker *backgroundworker.PeriodicWorker
}

func newHandler(ds datastore.DataStore, stream events.Stream) Handler {
Expand All @@ -47,6 +49,16 @@ func newHandler(ds datastore.DataStore, stream events.Stream) Handler {
stream: stream,
stopSignal: concurrency.NewSignal(),
}

h.flushWorker = &backgroundworker.PeriodicWorker{
Name: "admin-events-flush",
Interval: flushInterval,
Run: func(_ context.Context) error {
return h.ds.Flush(h.eventWriteCtx)
},
}
backgroundworker.Global.Register(h.flushWorker)

return h
}

Expand All @@ -58,30 +70,16 @@ func (h *handlerImpl) watchForEvents() {
}
}

func (h *handlerImpl) runDatastoreFlush() {
ticker := time.NewTicker(flushInterval)
defer ticker.Stop()

for {
select {
case <-ticker.C:
if err := h.ds.Flush(h.eventWriteCtx); err != nil {
log.Error(err)
}
case <-h.stopSignal.Done():
if err := h.ds.Flush(h.eventWriteCtx); err != nil {
log.Error(err)
}
return
}
}
}

func (h *handlerImpl) Start() {
go h.watchForEvents()
go h.runDatastoreFlush()
h.flushWorker.Start(context.Background())
}

func (h *handlerImpl) Stop() {
h.flushWorker.Stop()
// Final flush on stop preserves original behavior.
if err := h.ds.Flush(h.eventWriteCtx); err != nil {
log.Error(err)
}
h.stopSignal.Signal()
}
2 changes: 1 addition & 1 deletion central/administration/events/handler/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ func (s *handlerTestSuite) SetupTest() {

s.datastore = dsMocks.NewMockDataStore(s.mockCtrl)
s.eventStream = stream.GetStreamForTesting(s.T())
s.handler = newHandler(s.datastore, s.eventStream).(*handlerImpl)
flushInterval = 10 * time.Millisecond
s.handler = newHandler(s.datastore, s.eventStream).(*handlerImpl)
}

func (s *handlerTestSuite) TearDownTest() {
Expand Down
40 changes: 17 additions & 23 deletions central/declarativeconfig/manager_impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/stackrox/rox/central/declarativeconfig/updater"
declarativeConfigUtils "github.com/stackrox/rox/central/declarativeconfig/utils"
"github.com/stackrox/rox/generated/storage"
"github.com/stackrox/rox/pkg/backgroundworker"
"github.com/stackrox/rox/pkg/concurrency"
"github.com/stackrox/rox/pkg/declarativeconfig"
"github.com/stackrox/rox/pkg/declarativeconfig/transform"
Expand Down Expand Up @@ -60,8 +61,8 @@ type managerImpl struct {
nameExtractor types.NameExtractor
idExtractor types.IDExtractor

reconciliationTicker *time.Ticker
shortCircuitSignal concurrency.Signal
reconcileWorker *backgroundworker.PeriodicWorker
shortCircuitCh chan struct{}

reconciliationCtx context.Context

Expand Down Expand Up @@ -95,7 +96,7 @@ func New(reconciliationTickerDuration, watchIntervalDuration time.Duration, upda
errorsPerDeclarativeConfig: map[string]int32{},
idExtractor: idExtractor,
nameExtractor: nameExtractor,
shortCircuitSignal: concurrency.NewSignal(),
shortCircuitCh: make(chan struct{}, 1),
}
}

Expand Down Expand Up @@ -199,31 +200,24 @@ func (m *managerImpl) UpdateDeclarativeConfigContents(handlerID string, contents
// Note that the reconciliation loop will not be run if:
// - the short circuit loop signal has not been reset yet and is de-duped.
func (m *managerImpl) shortCircuitReconciliationLoop() {
// In case the signal is already triggered, the current call (and the Signal() call) will be effectively de-duped.
m.shortCircuitSignal.Signal()
select {
case m.shortCircuitCh <- struct{}{}:
default:
}
}

func (m *managerImpl) startReconciliationLoop() {
m.reconciliationTicker = time.NewTicker(m.reconciliationTickerDuration)

go m.reconciliationLoop()
}

func (m *managerImpl) reconciliationLoop() {
// While we currently do not have an exit in the form of "stopping" the reconciliation, still, ensure that
// the ticker is stopped when we stop running the reconciliation.
defer m.reconciliationTicker.Stop()
for {
select {
case <-m.shortCircuitSignal.Done():
log.Debug("Received a short circuit signal, running the reconciliation")
m.shortCircuitSignal.Reset()
m.runReconciliation()
case <-m.reconciliationTicker.C:
log.Debug("Received a ticker signal, running the reconciliation")
m.reconcileWorker = &backgroundworker.PeriodicWorker{
Name: "declarative-config-reconciler",
Interval: m.reconciliationTickerDuration,
ShortCircuit: m.shortCircuitCh,
Run: func(_ context.Context) error {
m.runReconciliation()
}
return nil
},
}
backgroundworker.Global.Register(m.reconcileWorker)
m.reconcileWorker.Start(context.Background())
}

func (m *managerImpl) runReconciliation() {
Expand Down
17 changes: 13 additions & 4 deletions central/processindicator/datastore/datastore.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
plopStore "github.com/stackrox/rox/central/processlisteningonport/store/postgres"
v1 "github.com/stackrox/rox/generated/api/v1"
"github.com/stackrox/rox/generated/storage"
"github.com/stackrox/rox/pkg/backgroundworker"
"github.com/stackrox/rox/pkg/concurrency"
"github.com/stackrox/rox/pkg/env"
"github.com/stackrox/rox/pkg/postgres"
Expand Down Expand Up @@ -56,12 +57,20 @@ func New(db postgres.DB, store store.Store, plopStorage plopStore.Store, prunerF
plopStorage: plopStorage,
prunerFactory: prunerFactory,
prunedArgsLengthCache: make(map[processindicator.ProcessWithContainerInfo]int),
stopper: concurrency.NewStopper(),
}
ctx := sac.WithAllAccess(context.Background())

if env.ProcessPruningEnabled.BooleanSetting() {
go d.prunePeriodically(ctx)
if env.ProcessPruningEnabled.BooleanSetting() && prunerFactory != nil {
ctx := sac.WithAllAccess(context.Background())
d.pruneWorker = &backgroundworker.PeriodicWorker{
Name: "process-indicator-pruner",
Interval: prunerFactory.Period(),
Run: func(runCtx context.Context) error {
d.prune(ctx)
return nil
},
}
backgroundworker.Global.Register(d.pruneWorker)
d.pruneWorker.Start(ctx)
}
return d
}
Expand Down
31 changes: 8 additions & 23 deletions central/processindicator/datastore/datastore_impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
plopStore "github.com/stackrox/rox/central/processlisteningonport/store/postgres"
v1 "github.com/stackrox/rox/generated/api/v1"
"github.com/stackrox/rox/generated/storage"
"github.com/stackrox/rox/pkg/backgroundworker"
"github.com/stackrox/rox/pkg/concurrency"
"github.com/stackrox/rox/pkg/env"
ops "github.com/stackrox/rox/pkg/metrics"
Expand Down Expand Up @@ -45,7 +46,7 @@ type datastoreImpl struct {
prunerFactory pruner.Factory
prunedArgsLengthCache map[processindicator.ProcessWithContainerInfo]int

stopper concurrency.Stopper
pruneWorker *backgroundworker.PeriodicWorker
}

func (ds *datastoreImpl) Count(ctx context.Context, q *v1.Query) (int, error) {
Expand Down Expand Up @@ -212,25 +213,6 @@ func (ds *datastoreImpl) IterateOverProcessIndicatorsRiskView(ctx context.Contex
return err
}

func (ds *datastoreImpl) prunePeriodically(ctx context.Context) {
defer ds.stopper.Flow().ReportStopped()

if ds.prunerFactory == nil {
return
}

t := time.NewTicker(ds.prunerFactory.Period())
defer t.Stop()
for {
select {
case <-t.C:
ds.prune(ctx)
case <-ds.stopper.Flow().StopRequested():
return
}
}
}

func (ds *datastoreImpl) getProcessInfoToArgs(ctx context.Context) (map[processindicator.ProcessWithContainerInfo][]processindicator.IDAndArgs, error) {
defer metrics.SetDatastoreFunctionDuration(time.Now(), "ProcessIndicator", "getProcessInfoToArgs")
processNamesToArgs := make(map[processindicator.ProcessWithContainerInfo][]processindicator.IDAndArgs)
Expand Down Expand Up @@ -289,9 +271,12 @@ func (ds *datastoreImpl) prune(ctx context.Context) {
}

func (ds *datastoreImpl) Stop() {
ds.stopper.Client().Stop()
if ds.pruneWorker != nil {
ds.pruneWorker.Stop()
}
}

func (ds *datastoreImpl) Wait(cancelWhen concurrency.Waitable) bool {
return concurrency.WaitInContext(ds.stopper.Client().Stopped(), cancelWhen)
func (ds *datastoreImpl) Wait(_ concurrency.Waitable) bool {
ds.Stop()
return true
}
37 changes: 20 additions & 17 deletions central/scannerdefinitions/handler/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
blob "github.com/stackrox/rox/central/blob/datastore"
"github.com/stackrox/rox/central/blob/snapshot"
"github.com/stackrox/rox/central/scannerdefinitions/file"
"github.com/stackrox/rox/pkg/backgroundworker"
"github.com/stackrox/rox/pkg/buildinfo"
"github.com/stackrox/rox/pkg/env"
"github.com/stackrox/rox/pkg/errox"
Expand Down Expand Up @@ -186,7 +187,25 @@ func New(blobStore blob.Datastore, opts handlerOpts) http.Handler {
log.Info("In online mode: scanner definitions will be updated automatically")

h.updaters = make(map[string]*requestedUpdater)
go h.cleanUpdatersPeriodic(opts.cleanupInterval, opts.cleanupAge)

interval := defaultCleanupInterval
if opts.cleanupInterval != nil {
interval = *opts.cleanupInterval
}
age := defaultCleanupAge
if opts.cleanupAge != nil {
age = *opts.cleanupAge
}
cleanupWorker := &backgroundworker.PeriodicWorker{
Name: "scanner-defs-cleanup",
Interval: interval,
Run: func(_ context.Context) error {
h.cleanupUpdaters(age)
return nil
},
}
backgroundworker.Global.Register(cleanupWorker)
cleanupWorker.Start(context.Background())

return h
}
Expand Down Expand Up @@ -762,22 +781,6 @@ func writeErrorForFile(w http.ResponseWriter, err error, path string) {
httputil.WriteGRPCStyleErrorf(w, codes.Internal, "could not read vulnerability definition %s: %v", filepath.Base(path), err)
}

func (h *httpHandler) cleanUpdatersPeriodic(cleanupInterval, cleanupAge *time.Duration) {
interval := defaultCleanupInterval
if cleanupInterval != nil {
interval = *cleanupInterval
}
age := defaultCleanupAge
if cleanupAge != nil {
age = *cleanupAge
}

t := time.NewTicker(interval)
for range t.C {
h.cleanupUpdaters(age)
}
}

func (h *httpHandler) cleanupUpdaters(cleanupAge time.Duration) {
now := time.Now()

Expand Down
57 changes: 27 additions & 30 deletions central/sensor/telemetry/controller_impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/pkg/errors"
"github.com/stackrox/rox/central/sensor/service/common"
"github.com/stackrox/rox/generated/internalapi/central"
"github.com/stackrox/rox/pkg/backgroundworker"
"github.com/stackrox/rox/pkg/centralsensor"
"github.com/stackrox/rox/pkg/concurrency"
"github.com/stackrox/rox/pkg/protocompat"
Expand All @@ -30,6 +31,9 @@ type controller struct {
injector common.MessageInjector

supportsCancellations bool

gcWorker *backgroundworker.PeriodicWorker
prevNilChans set.StringSet
}

type telemetryCallback func(ctx concurrency.ErrorWaitable, chunk *central.TelemetryResponsePayload) error
Expand All @@ -40,8 +44,15 @@ func newController(capabilities set.Set[centralsensor.SensorCapability], injecto
returnChans: make(map[string]chan *central.TelemetryResponsePayload),
injector: injector,
supportsCancellations: capabilities.Contains(centralsensor.PullTelemetryDataCap),
prevNilChans: set.NewStringSet(),
}
ctrl.gcWorker = &backgroundworker.PeriodicWorker{
Name: "telemetry-channel-gc",
Interval: telemetryChanGCPeriod,
Run: ctrl.pruneReturnChansOnce,
}
go ctrl.pruneReturnChans()
backgroundworker.Global.Register(ctrl.gcWorker)
ctrl.gcWorker.Start(context.Background())
return ctrl
}

Expand Down Expand Up @@ -230,34 +241,20 @@ func (c *controller) ProcessTelemetryDataResponse(ctx context.Context, resp *cen
}
}

func (c *controller) pruneReturnChans() {
prevNilChans := set.NewStringSet()
t := time.NewTicker(telemetryChanGCPeriod)
defer t.Stop()

for {
select {
case <-c.stopSig.Done():
return
case <-t.C:
}

// Go through all channels, and collect those that are nil. If we find a channel to be nil in two subsequent
// iterations, that means it has been in this state for `telemetryChanGCPeriod` and now can be removed.
newNilChans := set.NewStringSet()
concurrency.WithLock(&c.returnChansMutex, func() {
for id, retC := range c.returnChans {
if retC != nil {
continue
}

if prevNilChans.Contains(id) {
delete(c.returnChans, id)
} else {
newNilChans.Add(id)
}
func (c *controller) pruneReturnChansOnce(_ context.Context) error {
newNilChans := set.NewStringSet()
concurrency.WithLock(&c.returnChansMutex, func() {
for id, retC := range c.returnChans {
if retC != nil {
continue
}
prevNilChans = newNilChans
})
}
if c.prevNilChans.Contains(id) {
delete(c.returnChans, id)
} else {
newNilChans.Add(id)
}
}
})
c.prevNilChans = newNilChans
return nil
}
Loading