Help us shape the future of Go! Take the 2026 Go Developer Survey

peakmem

package
v0.9.3 Latest Latest
Warning

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

Go to latest
Published: Sep 24, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package peakmem reads the kernel-tracked peak resident memory of a finished task. Two entry points cover the two ways scitq runs a command:

  • Docker task: the container's cgroup carries a `memory.peak` file (cgroup v2, kernel 5.19+) or `memory.max_usage_in_bytes` (v1). ReadDockerPeakMB tries both, in order, and returns 0 on failure.

  • Bare task: /proc/<pid>/status carries a `VmHWM` field with the process's high-water resident-set size. ReadProcessPeakMB parses that and returns 0 on any read/parse error.

Both readers are best-effort by design: peak_mem_mb ends up in the task row as NULL when we can't read it, which the MCP surface treats as "not observed" rather than "zero used". There's no per-second sampling anywhere in this package — the kernel has been tracking the peak all along; we read the counter once, at task terminal.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ReadDockerPeakMB

func ReadDockerPeakMB(containerID string) int32

ReadDockerPeakMB reads the peak memory a docker container used, in MB (integer, rounded down). Tries the cgroup v2 file first, then the v1 fallback; both silently return 0 on any read error so a caller can always ship the returned value up without a nil check.

containerID is the full 64-char id, not the truncated "docker ps" display id. Callers typically get it from `docker inspect` or the output of `docker run --cidfile <path>`.

func ReadDockerPeakMBWithDiag

func ReadDockerPeakMBWithDiag(containerID string) (int32, []string)

ReadDockerPeakMBWithDiag is ReadDockerPeakMB plus a per-candidate diagnostic summary. Used by the executor to emit a worker_event when the read fails, so an operator can pinpoint the layout mismatch (missing path? path exists but reads 0? kernel too old for memory.peak?) without SSH-ing to the worker.

func ReadProcessPeakMB

func ReadProcessPeakMB(pid int) int32

ReadProcessPeakMB parses /proc/<pid>/status for VmHWM (peak resident memory). Returns 0 on any read/parse failure, or if the process has already been reaped and its /proc entry is gone.

VmHWM is reported in kilobytes ("VmHWM: 12345 kB"); we convert to MB (integer, rounded down) so the value fits an int32 comfortably even for terabyte-class processes.

Types

type Sampler

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

Sampler tracks the peak memory of a running docker container by re-reading the cgroup counter on a fixed cadence for the container's lifetime. This exists because a one-shot read at cmd.Wait return is UNRELIABLE on cgroup v2 with the systemd driver: systemd tears down docker-<CID>.scope as soon as the container process exits, and the memory.peak file is gone before the caller gets to it, even though `docker inspect` still returns metadata (Docker keeps its own container record independent of the cgroup scope). By sampling while the container is alive, the last observed value is a tight approximation of the true peak: memory.peak is monotonic, so a stale reading is a lower bound rather than a wrong number.

Zero-cost when the container never starts (goroutine exits after the CID-lookup deadline). Best-effort throughout: an unreadable file or a torn-down scope leaves Peak() at 0, and the caller sends NULL up.

func NewDockerSampler

func NewDockerSampler(containerName string, interval, startupDeadline time.Duration) *Sampler

NewDockerSampler starts a background goroutine that polls the peak memory of a docker container identified by containerName. The goroutine first waits for the container to be inspectable (up to startupDeadline) so callers can construct the sampler at the same time they run `docker run` without having to wait for the CID to become discoverable first. interval is how often to re-read the cgroup counter while the container is alive; 1 s is a fine default (memory.peak is monotonic, so a 1 s lag on the "final" reading is a tight bound on an hours-long workload).

func (*Sampler) Diag

func (s *Sampler) Diag() []string

Diag returns the last-known list of tried cgroup paths (with a present/missing/zero annotation), or nil if the sampler observed a good reading at least once. Intended for the caller's worker_event on peak==0 outcomes.

func (*Sampler) Stop

func (s *Sampler) Stop() int32

Stop signals the sampler to stop, waits for its final sample, and returns the highest observed peak in MB. Safe to call more than once — subsequent calls return the same value without blocking.

Jump to

Keyboard shortcuts

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