gc

package
v0.0.0-...-6ed2b60 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 19, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Overview

Package gc owns the agent's eviction work: the lingering-ghost sweep (this file) and pressure-relief eviction (pressure.go).

Deleted metadata lingers so a dying VM's FIN/RST packets still classify. The sweep then deletes kernel-first, then userspace, which preserves the kernel ⊆ userspace subset at every instant.

docs/architecture/data-structures.md#map-lifecycle-invariants

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type FlowEvictor

type FlowEvictor interface {
	Delete(key bpf.FlowKey) error
}

FlowEvictor deletes a flow entry from the kernel telemetry_map. Like MacEvictor it is the consumer-defined seam over a kernel map: the agent wires a *ebpf.Map adapter, tests wire a mock. Delete must be idempotent on a key that is already gone.

type FlowSettler

type FlowSettler interface {
	Settle(mode state.SettleMode, resolve func(bpf.FlowKey) (tenant, extNet, server string, ok bool)) int
}

FlowSettler folds flow rows into the settled-bytes accumulator. The sweep calls it at the last moment the MAC still resolves to its tenant, so the VM's lifetime bytes stay attributed. nil skips settling.

docs/architecture/data-structures.md#settled-bytes

type GhostSweeper

type GhostSweeper struct {
	// contains filtered or unexported fields
}

GhostSweeper periodically drops metadata entries whose 60s grace window has elapsed. Construct with New, then run GhostSweeper.Run on a long-lived goroutine.

func New

func New(opts Options) *GhostSweeper

New constructs a GhostSweeper from opts.

func (*GhostSweeper) Run

func (g *GhostSweeper) Run(ctx context.Context)

Run sweeps expired ghosts every interval until ctx is cancelled. It first blocks on boot.PhaseStateRestored so no eviction races the boot sequence; if the boot aborts (or ctx is cancelled) before that phase, Run returns without sweeping. There is no immediate first sweep: metadata is freshly populated at boot and ghosts need a full grace window to expire, so the first sweep fires one interval in.

type MacEvictor

type MacEvictor interface {
	Delete(mac uint64) error
}

MacEvictor deletes a MAC entry from the kernel mac_tenant_map. It is the consumer-defined seam over the kernel map: the agent wires a thin *ebpf.Map adapter, and tests wire a recording mock. Delete must be idempotent — a MAC already gone from the kernel is not an error.

type MacFlowEvictor

type MacFlowEvictor interface {
	DeleteFlowsForMACs(macs map[uint64]struct{}) (int, error)
}

MacFlowEvictor deletes a swept VM's residual telemetry_map counters, which outlive its MAC and would otherwise re-drain as "unknown". nil skips cleanup; best-effort, so a failure just means one flow may fold to unknown once.

docs/architecture/data-structures.md#lingering-ghost

type MapGauge

type MapGauge interface {
	SetCurrent(mapName string, value float64)
}

MapGauge refreshes the kernel mac_tenant_map current-entry gauge after the sweep deletes ghosts — cold-start sets it once, so without this it over-reports fill until the next reconcile. Consumer-defined seam; *bpf.Metrics satisfies it.

type Metrics

type Metrics struct {
	// contains filtered or unexported fields
}

Metrics holds the Prometheus instruments for the GC subsystem. The bundle owns both halves of the GC: the lingering-ghost sweep (this package's GhostSweeper) and pressure-relief eviction (run inside the scraper's drain goroutine, which holds a reference to this bundle). Keeping the lachesis_gc_evictions_total family in one place — rather than splitting it across two packages — means Prometheus registers each series once and the reason label is seeded whole.

The instruments are:

  • lachesis_gc_evictions_total{reason} counter
  • lachesis_gc_pressure_relief_runs_total counter
  • lachesis_gc_settled_flows_total counter
  • lachesis_lingering_ghosts_active gauge

func NewMetrics

func NewMetrics() *Metrics

NewMetrics constructs the bundle with both eviction reasons seeded at zero so lachesis_gc_evictions_total{reason="ttl"} and {reason="pressure_relief"} both exist before either path first fires.

func (*Metrics) Collectors

func (m *Metrics) Collectors() []prometheus.Collector

Collectors returns the underlying prometheus.Collector values for registration by the agent.

func (*Metrics) IncPressureReliefRuns

func (m *Metrics) IncPressureReliefRuns()

IncPressureReliefRuns increments lachesis_gc_pressure_relief_runs_total by one — call once per pressure-relief pass.

func (*Metrics) RecordPressureReliefEvictions

func (m *Metrics) RecordPressureReliefEvictions(n int)

RecordPressureReliefEvictions adds n telemetry_map evictions to lachesis_gc_evictions_total{reason="pressure_relief"}.

func (*Metrics) RecordResidualFlowEvictions

func (m *Metrics) RecordResidualFlowEvictions(n int)

RecordResidualFlowEvictions adds n telemetry_map flows deleted because their VM's MAC was swept, to lachesis_gc_evictions_total{reason="ghost_residual_flow"}.

func (*Metrics) RecordSettledFlows

func (m *Metrics) RecordSettledFlows(n int)

RecordSettledFlows adds n folded GlobalState rows to lachesis_gc_settled_flows_total.

func (*Metrics) RecordTTLEvictions

func (m *Metrics) RecordTTLEvictions(n int)

RecordTTLEvictions adds n lingering-ghost expiries to lachesis_gc_evictions_total{reason="ttl"}.

func (*Metrics) SetGhostsActive

func (m *Metrics) SetGhostsActive(n int)

SetGhostsActive sets lachesis_lingering_ghosts_active to the number of entries still inside their grace window after a sweep.

type Options

type Options struct {
	Meta        *metadata.ShardedMetadataMap
	Evictor     MacEvictor
	FlowEvictor MacFlowEvictor
	// Settler folds swept MACs' flow rows into the settled-bytes
	// accumulator before their metadata (the tenant binding) is
	// deleted. The agent wires its *state.GlobalState.
	Settler FlowSettler
	// Routers resolves each folded row's per-flow external_network
	// label ([metadata.FlowExternalLabel]) so the fold lands in exactly
	// the series the Collector was emitting. Optional (nil = per-VM
	// fallback only — pre-per-flow unit tests).
	Routers *metadata.RouterMACs
	// Tunables supplies the live sweep cadence (hot-reload; applies at
	// the next tick). REQUIRED — operational knobs have exactly one
	// source; unit tests construct a store with the values they
	// exercise.
	Tunables *tunables.Store
	// MapGauge refreshes the mac_tenant_map fill gauge after a sweep.
	// Optional (nil skips); the agent wires its bpf metrics bundle.
	MapGauge MapGauge
	Seq      *boot.Sequencer
	Metrics  *Metrics
}

Options bundles the inputs to New. Meta, Evictor, and Metrics are required; FlowEvictor is optional (nil skips residual-flow cleanup — used by tests without a kernel telemetry_map); Settler is optional (nil skips the settled-bytes fold — pre-fold unit tests); Seq is optional (nil skips the boot barrier — used by sweep-only unit tests); the sweep cadence is the live gc.ghost_sweep_interval tunable.

type PressureOptions

type PressureOptions struct {
	Evictor    FlowEvictor
	MaxEntries int
	Metrics    *Metrics
	Tunables   *tunables.Store
}

PressureOptions bundles the inputs to NewPressureReliever. All fields are required; MaxEntries must be positive (it is the fill-ratio denominator). The tuning values come from the shared tunables snapshot, validated at load/reload by config.GCConfig.

type PressureReliever

type PressureReliever struct {
	// contains filtered or unexported fields
}

PressureReliever evicts the oldest telemetry_map entries before the map fills, so the kernel never drops a counter on its own. It runs in the scraper's drain goroutine AFTER the readings are applied, so every evicted entry's bytes are already accounted ("flush before evict").

High/low watermark hysteresis with a per-pass cap: the map drains over a few scrapes rather than one long stall. All three bounds are hot-reloadable.

docs/architecture/data-structures.md#kernel-side-bpf-maps

func NewPressureReliever

func NewPressureReliever(opts PressureOptions) *PressureReliever

NewPressureReliever constructs a reliever. MaxEntries is the kernel telemetry_map's compiled-in capacity (bpf.MapTelemetryMaxEntries).

func (*PressureReliever) Relieve

func (p *PressureReliever) Relieve(drained map[bpf.FlowKey]bpf.FlowMetrics)

Relieve runs one pass over the just-drained readings, which are already in GlobalState. drained is read-only here: its key count IS the kernel population (read-don't-clear) and LastSeenNs is the eviction key. No-op outside a relief cycle.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL