Does: the figures behind usage.get, computed from the rows of history.db on a read thread.
Entry: index.ts → createUsageReader(deps) → { get(input), stop() }, one per dispatcher (worker or gateway).
Uses: contract (types), history (openUsageReads, row types), ports (NodeSqliteOpener). Never imports: leasing, drivers, daemon, gateway.
Callers: daemon/dispatcher.ts, gateway/dispatcher.ts. See history for the rows.
| File | Role |
|---|---|
index.ts |
createUsageReader: floors the window, owns the thread, joins token labels |
read-thread.ts |
Worker-thread entry: opens history.db read-only, reads, computes |
compute-usage.ts |
Pure: rows in, UsageOutput out; usageBucket picks the bucket width |
getanswersunavailablewhenopened()is false, without posting to the thread.usageBucket(from, to)picks the narrowest of 1, 5, 15 min, 1, 6 h, 1 day whose floored window has at most 200 points;fromis floored to it,tois as asked.- One thread, started on the first read, unreferenced. A second
getfor the same floored window while one runs gets the same promise; another window is another read. - The thread opens a read-only connection per read, runs one read transaction (
oldestTs,requestRows,minuteBuckets,deviceFacts) and answersnot-keptwhen the oldest row is later thanto. 4a. WithincludeLedgerthe thread, after the transaction commits, also turns the window's request rows intorequests[](ledgerOf, newest 100,000,ledgerTruncatedwhen cut); labels join as for requesters. The in-flight key includesincludeLedger. - Minute figures read whole minutes only (the minute still running at
tois left out), so a restart does not change them. - Labels are joined on the main thread from a fresh
tokenLabels(); a gateway takes itsrequesterPrefixoff an id first.
- Counting, samples, scopes and coverage live in
compute-usage.tsonly (architecture rule 10). - A read that throws, a thread that exits, or no answer in 30 s fails the call in flight; the next call starts a new thread.
stop()terminates the thread; the dispatchers call it fromdispose.- Under tests the thread runs the
.tsfile with a resolve hook that maps.jsimports to.ts.