Documentation
¶
Overview ¶
Package memctl provides periodic memory sampling with a caller-defined callback. The controller reads system, process, and cgroup memory metrics and calls a function with the results. Policy (what to do about memory pressure) lives in the callback — the controller is intentionally dumb.
On Linux, reads /proc/meminfo (MemAvailable), /proc/self/status (VmRSS), and cgroup v2 memory.current/memory.max. On other platforms, only Go runtime metrics are available.
The callback must be fast and non-blocking. Callbacks are invoked serially — no overlapping invocations. If a callback exceeds the interval, subsequent ticks are coalesced.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Watch ¶
Watch blocks, sampling memory every interval and calling fn with the results until ctx is canceled. Returns nil on clean cancellation. Returns an error if options are invalid.
Callbacks are invoked serially — no overlapping invocations. If a callback exceeds the interval, subsequent ticks are coalesced.
Types ¶
type BudgetStrategy ¶ added in v0.90.0
type BudgetStrategy interface {
// ComputeWorkers returns the recommended worker count for the
// given available memory (bytes) and CPU core count.
// Must return >= 1.
ComputeWorkers(availableMemory uint64, cpuCores int) int
}
BudgetStrategy computes the number of workers a stage should have based on available memory and CPU cores. Implementations encapsulate the sizing formula — consumers plug in a strategy instead of inline math in Watch callbacks.
type DefaultBudget ¶ added in v0.90.0
type DefaultBudget struct {
// BaseOverhead is memory reserved for non-worker use (bytes).
// Subtracted before dividing by PerWorkerCost.
BaseOverhead uint64
// PerWorkerCost is the memory cost per worker (bytes).
// Typically: model size + batch buffer + working set per worker.
PerWorkerCost uint64
// BudgetFraction is the fraction of available memory to use.
// Must be in (0, 1]. The rest is reserved as safety buffer.
BudgetFraction float64
// MaxCoresRatio caps workers relative to CPU cores.
// 0 means no CPU-based cap. Example: 2.0 = at most 2× cores.
MaxCoresRatio float64
// MaxWorkers is the absolute maximum. 0 means no cap.
MaxWorkers int
}
DefaultBudget computes workers from memory headroom using a simple linear model:
usable = availableMemory × BudgetFraction - BaseOverhead workers = min(usable / PerWorkerCost, cpuCores × MaxCoresRatio) workers = clamp(workers, 1, MaxWorkers)
func (DefaultBudget) ComputeWorkers ¶ added in v0.90.0
func (b DefaultBudget) ComputeWorkers(availableMemory uint64, cpuCores int) int
ComputeWorkers implements BudgetStrategy.
type MemInfo ¶
type MemInfo struct {
At time.Time // when this sample was taken
SystemAvailable uint64 // /proc/meminfo MemAvailable (bytes)
SystemAvailableOK bool
ProcessRSS uint64 // /proc/self/status VmRSS (bytes)
ProcessRSSOK bool
GoRuntimeTotal uint64 // runtime/metrics /memory/classes/total:bytes
GoRuntimeTotalOK bool
CgroupCurrent uint64 // cgroup v2 memory.current (bytes)
CgroupLimit uint64 // cgroup v2 memory.max (bytes; 0 = unlimited)
CgroupOK bool // true when cgroup v2 is detected and readable
}
MemInfo holds process and system memory information. Each metric has an OK flag — false means unavailable on this platform or a read error occurred, not "value is zero."
type Options ¶
type Options struct {
// Interval between memory samples. Must be > 0.
Interval time.Duration
// Immediate, when true, takes a sample immediately on entry
// before waiting for the first tick. Catches startup spikes.
Immediate bool
// OnPanic is called if the callback panics. If nil, the panic
// is re-raised (default: don't mask bugs). If non-nil, Watch
// logs the panic via OnPanic and continues sampling.
OnPanic func(any)
}
Options configures Watch.