Documentation
¶
Overview ¶
Package indexgc runs a bounded, best-effort background sweep that removes entity-store index (collection) entries the backing entity no longer justifies: the entity is gone, or it still exists but no longer carries the value the entry indexes.
It drains the backlog those leaks left and keeps a cluster self-healing without anyone running `miren debug reindex` by hand. Mismatched entries in particular cannot drain any other way, since no write path removes an indexed value the entity has already stopped carrying. It deliberately works off the read path: foreground reads stay pure and never issue deletes.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type GCConfig ¶
type GCConfig struct {
// CheckInterval is how often to run a sweep. A sweep resolves the entities
// behind every entry it scans whether or not it deletes anything, so a
// drained store pays a full read of itself on every tick. That cost, not
// the delete rate, is what sets this.
CheckInterval time.Duration
// MaxDeletesPerSweep caps deletions per sweep so a large backlog drains over
// several sweeps rather than one thundering pass. Zero means unbounded.
//
// Deletes are not the sweep's dominant cost, since every sweep resolves the
// entities behind the entries it scans regardless, so throttling them hard
// mostly stretches the drain.
MaxDeletesPerSweep int
// BatchPause is slept periodically during deletion to rate-limit write
// pressure. Zero disables pacing.
BatchPause time.Duration
// SweepTimeout bounds a single sweep. A truncated sweep is mostly fine: the
// pass is idempotent and the next one starts over, so finished work sticks.
//
// The caveat is that it restarts from the head of the keyspace, so a store
// too large for one sweep to scan would never reach its tail. A truncated
// sweep logs at Warn, which is the signal this needs a resume cursor.
SweepTimeout time.Duration
// InitialDelay is how long to wait before the first sweep. Zero means
// defaultInitialDelay; it is configurable so a test can drive the schedule.
InitialDelay time.Duration
}
GCConfig tunes the background sweep. Defaults are intentionally gentle: this is convergence insurance, not active firefighting, so it drains slowly and stays out of the way.
func DefaultGCConfig ¶
func DefaultGCConfig() GCConfig
DefaultGCConfig returns the default (gentle) configuration. At six hours and 5000 deletes a sweep, a backlog in the low hundreds of thousands drains in about a week, which is the right pace for entries that are bloat rather than a correctness problem.
type GCController ¶
type GCController struct {
Log *slog.Logger
Store *entity.EtcdStore
Config GCConfig
// contains filtered or unexported fields
}
GCController periodically removes stale collection entries from the entity store. It operates directly on the EtcdStore's CAS-guarded cleanup rather than going through the entity-access client, since it works below the index it is repairing.
func (*GCController) Start ¶
func (c *GCController) Start(ctx context.Context)
Start begins the periodic sweep.
func (*GCController) Stop ¶
func (c *GCController) Stop()
Stop cancels the sweep loop and waits for it to return, so a stopped controller is known to have stopped issuing deletes. Safe on a controller that was never started, and safe to call more than once.