phasetracking

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 4, 2026 License: MIT Imports: 1 Imported by: 0

Documentation

Overview

Package phasetracking accumulates cumulative time-in-phase for instance lifecycle phases. The tracker is embedded in instance metadata and updated at every externally-observable state transition so consumers can use the resulting durations for billing, observability, and analytics.

Phases mirror the externally-observable values of instances.State (lowercased so they remain stable in the API surface even if the internal enum is renamed). The Initializing→Running transition is detected lazily when guest boot markers are persisted, so the tracker reflects the same view of guest readiness that the public State machine reports — not the bare moment the VMM process came up.

Transient internal substates that no external observer can see — for example the Paused/Shutdown steps inside a single Standby or Stop orchestration — are intentionally not recorded; they would be sub-millisecond blips inside a non-yielding function call that adds noise without truth.

Only the transition orchestration sites in lib/instances should call Record. The tracker intentionally does not subscribe to the lifecycle event bus — that bus is best-effort and lossy, which is unsuitable for billing.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Phase

type Phase string

Phase is the canonical lifecycle phase name. Values mirror instances.State lowercased so they remain stable in the API surface even if the internal State enum is renamed.

const (
	PhaseStopped      Phase = "stopped"
	PhaseCreated      Phase = "created"
	PhaseInitializing Phase = "initializing"
	PhaseRunning      Phase = "running"
	PhaseStandby      Phase = "standby"
)

type Tracker

type Tracker struct {
	Current    Phase           `json:"current,omitempty"`
	Since      time.Time       `json:"since,omitempty"`
	Cumulative map[Phase]int64 `json:"cumulative,omitempty"`
}

Tracker accumulates cumulative wall-clock time spent in each phase.

Invariants:

  • Cumulative[phase] is the total ms spent in `phase` across all prior completed visits to that phase.
  • Time spent in the *current* phase (since `Since`) is NOT yet rolled into Cumulative — callers that want "live" totals should use Snapshot.
  • Current and Since must be updated atomically with Cumulative; that's the contract of Record. Direct mutation is not supported.

The zero value is valid: it represents an instance that has not entered any phase yet. The first Record call sets Current and Since without accruing time (there is no prior phase to accrue from).

func (Tracker) Clone

func (t Tracker) Clone() Tracker

Clone returns a deep copy of the tracker. The returned tracker shares no state with the receiver, so independent Record/Reset calls do not interfere.

func (*Tracker) Record

func (t *Tracker) Record(newPhase Phase, now time.Time)

Record transitions into newPhase as of `now`, first accruing time-in-current into Cumulative. Safe to call on a zero-value Tracker (first transition has no prior phase, so no accrual happens).

`now` is a parameter rather than time.Now() so tests can pin time and so callers can use the same `now` value they're persisting elsewhere on the metadata (e.g. StartedAt) without drift.

func (*Tracker) Reset

func (t *Tracker) Reset()

Reset clears all accumulated state. Used when forking — the fork is a new instance and must not inherit the source's phase history.

func (Tracker) Snapshot

func (t Tracker) Snapshot(now time.Time) map[Phase]int64

Snapshot returns a copy of Cumulative with the in-flight time-in-current rolled in, without mutating the tracker. Use this when reporting "running time so far" — typically in the API response path.

Jump to

Keyboard shortcuts

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