Hyper.Node.FireVMM.Meter (Hyper v0.1.0)

Copy Markdown View Source

Per-VM compute meter: samples the VM's cgroup cpu.stat every second, accrues the CPU time actually executed, and flushes one Hyper.Metering.Usage window per minute — plus a final one at teardown. The meter is the FireVMM supervisor's last child, so at shutdown it stops first, taking its final reading before the Daemon removes the cgroup.

Billing-grade by construction:

  • consumption is accrued from counter deltas (Controls.Accumulator), so a cgroup recreated by a Core restart re-baselines instead of going negative;
  • the accumulator is baselined at meter start, not at the first periodic tick: a leaf that already exists is baselined on its current reading (a restarted meter never re-bills usage a previous incarnation flushed), and a leaf the jailer has not yet created is baselined at zero (its counter is born at zero), so a VM that lives and dies inside one sample interval still has its whole life covered by the final reading in terminate/2;
  • a failed flush keeps the accrued time and retries with the window extended; the retry is idempotent on (vm_id, window_start), so an insert that committed but errored client-side is dropped, not double-billed — recorded usage can never be counted twice;
  • every failure mode (meter crash, node crash, unreadable cgroup) loses at most the unflushed window: metering only ever under-counts, never over-counts.

Observability contract: because empty windows are dropped without a write, every drop is logged with the meter's lifetime sample/window counters. A drop on a VM that has already recorded usage is a normal idle window and logs at debug; a drop on a VM that has never recorded a window means the VM's entire life produced no usage row — every cgroup read failed, or the guest genuinely burned no measurable CPU after the start-of-life baseline — and logs at warning. Per-sample cpu.stat read failures log at debug (they are expected while the jailer is still creating the leaf) and are counted.

Summary

Functions

Returns a specification to start this module under a supervisor.

CPU time accrued by vm_id's meter but not yet flushed to the usage table. Unit.Time.zero() when no meter is reachable (VM stopped, meter mid-restart) — callers fall back to the flushed record, an under-count of at most one flush window.

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

start_link(opts)

unflushed(vm_id)

@spec unflushed(Hyper.Vm.Id.t()) :: Unit.Time.t()

CPU time accrued by vm_id's meter but not yet flushed to the usage table. Unit.Time.zero() when no meter is reachable (VM stopped, meter mid-restart) — callers fall back to the flushed record, an under-count of at most one flush window.