Skip to main content

Class: SqlSpendMeter

Defined in: packages/agentos/src/safety/runtime/SqlSpendMeter.ts:307

A persisted per-account meter. Every method is safe to call from several processes at once against one store: two reservations cannot both take the last unit, and a reservation settles exactly once.

Implements​

Constructors​

Constructor​

new SqlSpendMeter(opts): SqlSpendMeter

Defined in: packages/agentos/src/safety/runtime/SqlSpendMeter.ts:319

Parameters​

opts​

SqlSpendMeterOptions

Returns​

SqlSpendMeter

Methods​

ensureSchema()​

ensureSchema(): Promise<void>

Defined in: packages/agentos/src/safety/runtime/SqlSpendMeter.ts:351

Creates the tables and their indexes unless the tables answer a read already. On tables that answer it reads the store's catalogue for the meter's index names (pg_indexes on Postgres, sqlite_master on SQLite) and runs the CREATE INDEX IF NOT EXISTS statement of each index the tables lack, so a store an earlier release made gains the indexes it lacks, and a store that holds them all runs no index statement: on Postgres each one takes a SHARE lock on the reservations table, which holds back the table's writes, before it looks for the index's name. An index statement that fails is reported to SqlSpendMeterOptions.onWarning, and the meter uses the tables as they are. Called before the first statement; safe to call again. Does nothing with ensureSchema: false.

Returns​

Promise<void>


heartbeat()​

heartbeat(operationId, now?): Promise<void>

Defined in: packages/agentos/src/safety/runtime/SqlSpendMeter.ts:581

Pushes a live reservation's lease forward while its turn runs.

Parameters​

operationId​

string

now?​

number = ...

Returns​

Promise<void>

Implementation of​

ISpendMeter.heartbeat


purge()​

purge(opts): Promise<SpendPurgeResult>

Defined in: packages/agentos/src/safety/runtime/SqlSpendMeter.ts:739

Deletes the reservations settled before before and, with a window, the account rows not updated since then that hold nothing reserved, at most limit of each (default 1,000): the retention a product's terms set. It deletes from this meter's own two tables, across every account in them, so a meter under a prefix of its own keeps its own retention. A reservation still reserved is never deleted, nor is a period meter's period row, which holds the period's count. With a window, a before at least one window back keeps every unit the window counts. An operation retried after its row was purged counts again, so before lies past the time a retry can come.

Parameters​

opts​
before​

number

limit?​

number

Returns​

Promise<SpendPurgeResult>


reconcile()​

reconcile(opts?): Promise<SpendReconcileResult>

Defined in: packages/agentos/src/safety/runtime/SqlSpendMeter.ts:610

Settles the expired reservations, at most limit a pass (default 100), the earliest expiry first. With resolveExpired the host decides each one: consumed, released, or deferred, which keeps it reserved and counted with its evidence and its next check on its row. Without it an ordinary reservation settles as resolveUnknown and unknownAfterLease say, and one made with requireFence, or deferred before, stays reserved and counts as pending; such a pass reads the ordinary reservations into its page first and the fenced holds only into the room they leave, each in expiry order, so the fenced holds it leaves never take the place of one it can settle, and no pass sorts every due row to find its page.

Each decision is written to the reservation as the pass read it, in one conditional statement: the same attempt, still reserved, still past its lease at now and, for a settlement without resolveExpired, still unfenced. So no decision lands on a newer attempt of the operation, and none replaces a lease that a heartbeat renewed, or a next check after now that another pass deferred it to, while the resolver was asked; on a meter without resolveExpired a settlement also never takes a reservation an opted-in pass fenced meanwhile. The pass drops such a decision.

Parameters​

opts?​
limit?​

number

now?​

number

Returns​

Promise<SpendReconcileResult>

Implementation of​

ISpendMeter.reconcile


reserve()​

reserve(req): Promise<SpendReserveResult>

Defined in: packages/agentos/src/safety/runtime/SqlSpendMeter.ts:421

Reserves units for an operation, or refuses. Rejects with SpendMeterUnavailableError when the store cannot answer.

Parameters​

req​

SpendReserveRequest

Returns​

Promise<SpendReserveResult>

Implementation of​

ISpendMeter.reserve


setAllowance()​

setAllowance(accountId, allowance, now?): Promise<void>

Defined in: packages/agentos/src/safety/runtime/SqlSpendMeter.ts:712

Writes the current period's allowance at once after a plan change; the units used stay. A store that reads the product's allowance at every reservation takes the product's answer again at the next one.

Parameters​

accountId​

string

allowance​

number

now?​

number = ...

Returns​

Promise<void>

Implementation of​

ISpendMeter.setAllowance


settle()​

settle(req): Promise<SpendSettleResult>

Defined in: packages/agentos/src/safety/runtime/SqlSpendMeter.ts:527

Settles an operation's reservation. Idempotent per operation and outcome.

Parameters​

req​

SpendSettleRequest

Returns​

Promise<SpendSettleResult>

Implementation of​

ISpendMeter.settle


snapshot()​

snapshot(accountId, now?): Promise<SpendMeterSnapshot>

Defined in: packages/agentos/src/safety/runtime/SqlSpendMeter.ts:687

The account's current period: its allowance, the units used and reserved, and what remains.

Parameters​

accountId​

string

now?​

number = ...

Returns​

Promise<SpendMeterSnapshot>

Implementation of​

ISpendMeter.snapshot


startReconciler()​

startReconciler(intervalMs?, onError?): void

Defined in: packages/agentos/src/safety/runtime/SqlSpendMeter.ts:768

Runs reconcile every interval until stopReconciler. A failed pass is retried on the next tick.

Parameters​

intervalMs?​

number = 15_000

onError?​

(e) => void

Returns​

void


stopReconciler()​

stopReconciler(): void

Defined in: packages/agentos/src/safety/runtime/SqlSpendMeter.ts:776

Returns​

void