Files
suaveplan/packages/devtools/tooling/profiler/src/sampler/sampler.md
2026-05-27 23:29:53 +01:00

2.7 KiB

sampler

(no submodules)

Purpose

Sampler collects periodic snapshots of runtime metrics (memory usage by default, plus caller-supplied custom metrics). The timer source is injected through a TimersLike so tests can advance virtual time deterministically and so non-setInterval runtimes (Workers, Deno, embedded JS) can plug in their own scheduler. Sample storage is capped via FIFO eviction so long-running collectors don't leak memory.

Features

  • Zod-validated options (intervalMs > 0, optional positive maxSamples, optional captureMemory).
  • Injectable Clock, TimersLike, and MemoryProbe — the defaults read Date.now, setTimeout/clearTimeout, and process.memoryUsage/performance.memory respectively.
  • start() / stop() are idempotent — double-start and double-stop are no-ops.
  • takeSample(customMetrics?) records a single sample on demand; same code path used by the scheduled tick.
  • getSamples() / getSamplesInRange(start, end) / clear() for retrieval and reset.
  • events: EventBus<SamplerEventMap> emits sampler:start, sampler:stop, sampler:sample.
  • Telemetry: profiler_samples_total counter incremented on every sample.

Usage: Basic

import { Sampler } from "@suaveplan/profiler";

const sampler = new Sampler({ intervalMs: 1000 });
sampler.start();
// ...
sampler.stop();
console.log(sampler.getSamples());

Usage: Advanced

import { Sampler } from "@suaveplan/profiler";
import type { TimersLike } from "@suaveplan/types";

const queue: Array<{ cb: () => void; handle: number }> = [];
let next = 1;
const fakeTimers: TimersLike = {
    setTimer(cb) {
        const handle = next++;
        queue.push({ cb, handle });
        return handle;
    },
    clearTimer() {},
};

let clockT = 0;
const sampler = new Sampler({
    intervalMs: 10,
    timers: fakeTimers,
    clock: () => clockT,
    memoryProbe: () => 4096,
});
sampler.start();
clockT = 10;
queue.shift()?.cb();

API Reference

  • class Sampler — new Sampler(options: SamplerOptions).
  • interface SamplerOptions extends SamplerConfig { clock?, timers?, memoryProbe? }.
  • Methods: start, stop, takeSample, getSamples, getSamplesInRange, isRunning, clear.
  • Errors: throws ProfilerError with PROFILER.INVALID_OPTIONS when options fail Zod validation.

Implementation Notes

The scheduler uses a self-rescheduling setTimer rather than setInterval because TimersLike only models one-shot timers. Each tick checks this.running before taking a sample, which lets a stop() that runs between callback dispatch and execution avoid emitting a stale sample. FIFO eviction uses splice(0, n) so the oldest samples drop out when maxSamples is exceeded.