samples

package
v1.801.458 Latest Latest
Warning

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

Go to latest
Published: Aug 5, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Overview

Package samples is the fleet's compute-utilization time series: ONE table, ONE writer seam, ONE read face that every compute source feeds.

The fleet already reports lifecycle, liveness and static inventory — the Visor machines, the BYO workers that dialed in, the BYO clusters, the agent run-targets. None of it answers "how hot is this GPU / how loaded is this machine, over time, per org": hanzo.compute_usage is spend/lifecycle-shaped (org, app, project, kind, event, machine_id, size, price_cents, ts) and carries no cpu/mem/gpu, and o11y's samples_v4 carries no org. An agent run-target does carry a real Spec + Metrics, but only the LAST one — a snapshot on the row, not a series. This package is the missing plane, and it is the ONLY one: sources append here rather than growing private telemetry tables.

It is deliberately a LEAF. It depends on the datastore seam (ai/object) and the tenancy vocabulary (apps/principal) and nothing else in cloud, so every compute source — apps/agents, apps/visor, ml — can import it without a cycle (apps/link imports apps/agents, and apps/agents imports this).

  • Record(ctx, Sample) append one utilization sample (samples.go)
  • Series(ctx, Query) an org's samples over a bounded window (read.go)
  • Latest(ctx, org) each unit's most recent sample, for a fleet board

ISOLATION: org is the ONLY tenant key. It leads every statement as a BOUND parameter (never interpolated), and a blank or oversized org fails CLOSED on both the write and the read — a caller for org A can never write into, or read, org B's series. The caller MUST pass an org it already validated server-side (principal.Org / a verified claim), never a raw client header.

AVAILABILITY: the warehouse is never in a caller's critical path. With no datastore configured, Record is a no-op that returns nil — a heartbeat, a session or a board must never fail because the time series is absent.

Index

Constants

View Source
const (
	SourceAgent = "agent" // a linked run-target's heartbeat (clients/agents)
	SourceBYO   = "byo"   // a bring-your-own worker or cluster that dialed in
	SourceCloud = "cloud" // a cloud workload
	SourceVisor = "visor" // a Visor-provisioned machine
)

Sources — the CLOSED vocabulary of compute planes that feed the series. Closed (validated, never coerced) so `source` stays a real dimension: an unknown source is a wiring bug, and silently storing it would quietly fragment every rollup.

View Source
const (
	KindLaptop  = "laptop"
	KindCloud   = "cloud"
	KindGPU     = "gpu"
	KindCluster = "cluster"
	KindMachine = "machine"
	KindWorker  = "worker"
)

Kinds — the CLOSED vocabulary of compute units. The first five mirror the agent run-target kinds (clients/agents.Target*); `worker` is the BYO fleet's own unit, which is presence, not a dispatch destination. This is the fleet-wide superset, deliberately NOT an import of the agents vocabulary: agents owns "what an agent can be dispatched to", this owns "what the fleet can meter". They overlap today and are free to diverge without either dragging the other.

View Source
const DefaultRange = "24h"

DefaultRange is the window a read gets when ?range is absent or unrecognized.

Variables

View Source
var ErrInvalid = errors.New("samples: invalid request")

ErrInvalid marks a CALLER's error — a malformed tenant or an out-of-vocabulary narrower — as categorically distinct from an infrastructure failure. The two must never be conflated at an HTTP face: an unknown ?source is a 400 whose text is safe to echo (it is our own closed vocabulary), whereas a warehouse failure is neither the caller's fault nor theirs to read — its text names our tables and hosts. Faces branch on errors.Is(err, ErrInvalid).

Functions

func Latest

func Latest(ctx context.Context, o string) (map[string]Sample, error)

Latest returns each of the org's units keyed by unit id, with its most recent sample inside latestWindow. A blank org fails closed; an absent datastore is an honest empty map, which a board renders as "no samples yet" rather than failing.

func Record

func Record(ctx context.Context, s Sample) error

Record appends one utilization sample to the series.

Fail-SOFT on absence, fail-CLOSED on nonsense — the two are different and are reported differently:

  • No datastore configured (DatastoreEnabled() == false): a no-op returning nil. The time series is optional infrastructure; its absence must never fail or stall the heartbeat, session or board that emitted the sample.
  • A blank/oversized org, a blank/oversized unit, or an unknown source/kind: an error and NO write. An untenanted or misattributed row is worse than no row at all.

It is synchronous and honours the ctx it is given — the CALLER owns the concurrency policy, exactly as the billing warehouse write does (`go zapWriteUsage(...)`). An emitter on a request path should hand it a DETACHED, bounded context so neither a slow warehouse nor a client disconnect can touch its own contract.

Types

type Query

type Query struct {
	Org    string
	Unit   string
	Source string
	Range  string
}

Query is a resolved, already-authorized read. Org is the tenant and is REQUIRED — the controller fills it from the validated principal, never from a client field. Unit/Source narrow within that tenant; Range is an allowlisted label.

type Sample

type Sample struct {
	Org    string // the tenant — the ONLY tenancy key
	Source string // agent | byo | cloud | visor
	Unit   string // the source's own id for this unit
	Host   string // the hostname the unit reports (may be empty)
	Kind   string // laptop | cloud | gpu | cluster | machine | worker
	At     time.Time

	CPUs     int   // logical cores
	Memory   int64 // total RAM, bytes
	MemUsed  int64 // bytes
	MemFree  int64 // bytes
	Load1    float64
	Load5    float64
	Load15   float64
	GPUUtil  float64 // 0..1 aggregate utilization
	GPUs     int     // accelerator count
	GPUModel string  // the representative accelerator ("GB10"); GPUs carries the count

	CostCents int64 // the resale price of this unit for this sample's hour; 0 when unpriced
}

Sample is one utilization measurement of one compute unit at one instant — the value the whole plane is built around. Org/Source/Unit/Kind identify it, At is when it was measured (server-stamped by the caller; a zero value means "now"), and the rest is what the unit WAS and was DOING at that instant.

The static capability (CPUs/Memory/GPUs/GPUModel) rides every row on purpose: the series then answers "how hot was this GPU" without a join against a registry whose row may have since been rewritten or deregistered. A sample is a fact, and a fact carries its own context.

func Series

func Series(ctx context.Context, q Query) ([]Sample, error)

Series returns the org's samples over a bounded window, oldest first — the data behind a utilization chart. A blank org fails closed; an absent datastore is an honest empty (never fabricated zeros).

Jump to

Keyboard shortcuts

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