metering

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Sep 15, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Package metering folds each candidate resource's event history into the usage drafts of one billing period: the intervals the fold implies, clipped to the period, carrying the quantities every later number is derived from. It persists nothing. Writing the usage rows and the run's stats belongs to a later package, so a period can be metered without a handle on the database it will be written to.

Every draft of a resource is held against internal/engine/invariants before it is handed out. A breach fails the whole resource set with a report of every violating resource rather than letting one wrong resource through.

The normative specification is roadmap/03-phase-3-metering-rating.md, WP 3.3.

Index

Constants

View Source
const InvariantReservedUsageField = "reserved_usage_field"

InvariantReservedUsageField is what a resource whose size carries one of those names is reported as. It stands beside the invariants package's own codes in a run's violation report rather than in that package: such a resource has no drafts to hold against an invariant, so the breach is found here, one step before invariants.Check runs.

View Source
const WarningCandidateWithoutHistory = "candidate_without_history"

WarningCandidateWithoutHistory marks a candidate the projection lists whose events are missing or all lie at or after the period end. It is metered as nothing, because there is no history to bill it from.

Variables

This section is empty.

Functions

This section is empty.

Types

type ResourceUsage

type ResourceUsage struct {
	Resource source.Resource
	Drafts   []UsageDraft
}

ResourceUsage is one resource and the drafts the period bills it as.

type ResourceViolations

type ResourceViolations struct {
	Cloud        string                 `json:"cloud"`
	ResourceType string                 `json:"resource_type"`
	ResourceID   string                 `json:"resource_id"`
	Violations   []invariants.Violation `json:"violations"`
}

ResourceViolations is one resource and the metering rules it breached: the invariants its drafts failed, or the reserved usage field that stopped the drafts from being built at all.

type Result

type Result struct {
	// Candidates counts every candidate examined, including those that yielded
	// no drafts.
	Candidates int
	Resources  []ResourceUsage
	Warnings   []Warning
}

Result is what one metering pass produced.

func Meter

func Meter(ctx context.Context, src Source, periodFrom, periodTo time.Time, clouds []string) (*Result, error)

Meter folds every candidate of the period into its drafts. The candidates of the named clouds are read from src, and each one's history is loaded, folded, and checked on its own: the loop runs sequentially over the one connection the snapshot holds and holds a single resource's events at a time, which is what lets a resource with years of history be metered at all. The drafts are the other half of the footprint, and they are all kept until Meter returns: the pass hands out every resource's usage or none of it, so there is nothing it could hand on early.

A resource whose drafts breach an invariant is collected rather than returned on, so that the error names every violating resource of the period. Any violation fails the whole pass: the error is a *ViolationError and no drafts come back with it.

The errors of src are returned unchanged, so a caller reads a canceled context or a failed query as the source reported it. A resource whose size carries one of the reserved usage fields is collected the same way a breached invariant is: it is a resource nothing can bill correctly, and one such size persists in the events table and reaches every later period, so a run that named one of them and stopped would have an operator fix the period's resources one run at a time.

type Source

type Source interface {
	Candidates(ctx context.Context, clouds []string, periodFrom, periodTo time.Time) ([]source.Resource, error)
	History(ctx context.Context, r source.Resource, periodTo time.Time) ([]event.Stored, error)
}

Source is what metering reads a period from, implemented by *source.Snapshot. The interface lives here rather than next to that type so the loop below can be exercised without a database.

type UsageDraft

type UsageDraft struct {
	State, ProjectID string
	FromTS, ToTS     time.Time
	Seconds          int64
	Usage            map[string]any
}

UsageDraft is one interval of a resource clipped to the billing period. Seconds is the whole seconds of [FromTS, ToTS), a sub-second remainder truncated (D2), and Usage is decision D9's object: every size field of the interval verbatim, plus the minutes those seconds are worth and the count of one that prices a resource by its existence.

func MeterResource

func MeterResource(events []event.Stored, periodFrom, periodTo time.Time) ([]UsageDraft, error)

MeterResource folds one resource's history into the drafts the period [periodFrom, periodTo) bills it as. It is the whole of what metering computes; Meter is this over a source's candidate list.

A history that is empty, or a period with no length, bills nothing and yields an empty slice. An interval whose size carries one of the reserved usage fields is an error rather than a draft.

type ViolationError

type ViolationError struct {
	Resources []ResourceViolations
}

ViolationError is what Meter fails a period with: every resource the period cannot be billed from, and nothing else. No drafts come back with it, because a run that found one wrong resource keeps no partial output.

func (*ViolationError) Error

func (e *ViolationError) Error() string

Error reports how many resources breached an invariant. The breaches themselves are in Resources, which the run writes to its stats.

type Warning

type Warning struct {
	Cloud        string `json:"cloud"`
	ResourceType string `json:"resource_type"`
	ResourceID   string `json:"resource_id"`
	Code         string `json:"code"`
}

Warning names a resource that was metered on incomplete data. Code is WarningCandidateWithoutHistory or timeline.WarningHistoryStartsWithoutCreate. A warning does not fail the run: it reaches an operator through the run's stats.

Jump to

Keyboard shortcuts

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