mirror of
https://github.com/stablyai/orca.git
synced 2026-11-01 01:27:35 +00:00
perf(usage): keep per-source usage caches off the main thread (#26980)
* perf(usage): keep per-source usage caches off the main thread The usage stores kept every provider's per-source scan cache (processedFiles / processedDatabases) inside the one JSON file main loads at startup. On a large Claude history that file is 56 MB, 43 MB of it per-source records only a scan reads, so main paid a sync read+parse at launch, a structured clone of the whole cache to and from the scan worker on every scan, and a pretty-printed rewrite after every scan. The usage scan worker now owns those records in a sidecar (`<cache>-sources.json`): it reads it before a scan, writes it after (compact, durable rename), and returns only sessions and daily aggregates. Main keeps and writes only that report, compact. A cache still carrying inline records is split on the worker the first time it is loaded (above 8 MB); smaller ones parse on main and rescan cold. Sync IPC getters and automation lookups wait for the load. Synthetic 56 MB cache, same machine, interleaved runs: - first launch: 108 ms sync parse -> 18 ms main busy, 4 ms longest block - later launches: ~69 ms -> ~7 ms - forced scan, longest main-thread block: 89 ms -> 11 ms (real built app, headless: 84-94 ms -> 11-13 ms) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(usage): preserve cache attribution and legacy warm scans * fix(usage): reclaim cache temps after worker retirement --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Neil <neil@stably.ai>
This commit is contained in:
co-authored by
Claude Opus 5.5
Neil
parent
618dc62889
commit
09aff1b94d
@@ -0,0 +1,46 @@
|
||||
import type {
|
||||
OpenCodeUsageDailyAggregate,
|
||||
OpenCodeUsagePersistedDatabase,
|
||||
OpenCodeUsagePersistedState
|
||||
} from './types'
|
||||
|
||||
/** Fills cost fields older OpenCode caches never wrote. Electron-free: the scan worker runs it too. */
|
||||
export function normalizeOpenCodeUsagePersistedDatabases(
|
||||
databases: OpenCodeUsagePersistedDatabase[] | undefined
|
||||
): OpenCodeUsagePersistedDatabase[] {
|
||||
return (databases ?? []).map((database) => ({
|
||||
...database,
|
||||
sessions: (database.sessions ?? []).map(normalizeSessionCost),
|
||||
dailyAggregates: (database.dailyAggregates ?? []).map(normalizeDailyAggregateCost)
|
||||
}))
|
||||
}
|
||||
|
||||
export function normalizeDailyAggregateCost(
|
||||
entry: OpenCodeUsageDailyAggregate
|
||||
): OpenCodeUsageDailyAggregate {
|
||||
return {
|
||||
...entry,
|
||||
estimatedCostUsd: entry.estimatedCostUsd ?? null
|
||||
}
|
||||
}
|
||||
|
||||
export function normalizeSessionCost(
|
||||
session: OpenCodeUsagePersistedState['sessions'][number]
|
||||
): OpenCodeUsagePersistedState['sessions'][number] {
|
||||
return {
|
||||
...session,
|
||||
estimatedCostUsd: session.estimatedCostUsd ?? null,
|
||||
locationBreakdown: (session.locationBreakdown ?? []).map((entry) => ({
|
||||
...entry,
|
||||
estimatedCostUsd: entry.estimatedCostUsd ?? null
|
||||
})),
|
||||
modelBreakdown: (session.modelBreakdown ?? []).map((entry) => ({
|
||||
...entry,
|
||||
estimatedCostUsd: entry.estimatedCostUsd ?? null
|
||||
})),
|
||||
locationModelBreakdown: (session.locationModelBreakdown ?? []).map((entry) => ({
|
||||
...entry,
|
||||
estimatedCostUsd: entry.estimatedCostUsd ?? null
|
||||
}))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user