#[non_exhaustive]pub struct UsageEvent {
pub request_id: RequestId,
pub account_id: AccountId,
pub source: UsageSource,
pub units: CostUnits,
pub occurred_at: Timestamp,
pub policy_revision: PolicyRevision,
pub key_id: Option<KeyId>,
}Expand description
One committed charge. Produced only from a committed
crate::reservation::Reservation; there is deliberately no public
constructor path for uncommitted work.
#[non_exhaustive] is what makes that sentence true outside this crate
rather than merely stated. The type had said “produced only from a
committed reservation” while remaining a plain struct literal any crate
could fill in, which is a convention rather than a boundary; a caller could
assemble an event for work that never committed and hand it to a sink.
Construction now goes through UsageEvent::new, and the sealing has a
second benefit the workspace pays for once: a field added here no longer
breaks every literal in every downstream test.
Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.request_id: RequestIdIdempotency key: a sink must treat a replayed request_id as the same
charge, not a new one.
The only field of this struct that is independent of how the units were funded, which is what lets overage replay under the same rule as any other event (INVARIANTS.md GL-7).
account_id: AccountId§source: UsageSourceWhat funded the units, and the evidence the sink validates.
units: CostUnits§occurred_at: Timestamp§policy_revision: PolicyRevisionThe consuming application’s policy identity, copied from the pinned snapshot that priced this request (GL-94).
Carried so a billing record can be traced to the exact product policy
that produced it. Tollgate never reads it, and an event from a
publisher that stated no revision carries
PolicyRevision::UNSTATED.
Defaults on the wire, so an ingest from a peer that predates the field decodes rather than failing — the same rule the snapshot’s optional fields follow.
key_id: Option<KeyId>Credential named by the pinned, key-scoped snapshot. An absent value preserves billing but supplies no credential activity. This metadata is never authorization evidence; the sink checks account ownership.
Implementations§
Source§impl UsageEvent
impl UsageEvent
Sourcepub const fn new(
request_id: RequestId,
account_id: AccountId,
source: UsageSource,
units: CostUnits,
occurred_at: Timestamp,
policy_revision: PolicyRevision,
key_id: Option<KeyId>,
) -> Self
pub const fn new( request_id: RequestId, account_id: AccountId, source: UsageSource, units: CostUnits, occurred_at: Timestamp, policy_revision: PolicyRevision, key_id: Option<KeyId>, ) -> Self
Build a committed charge.
Called by Reservation::usage_event, which is the only place that
can prove the charge committed. It is public because tests, benchmarks,
and store backends across the workspace need to construct events
without a live reservation; what #[non_exhaustive] buys is that every
such construction goes through one signature, so a new field reaches
them as a compile error at one call each rather than as a silent
default.