-
Notifications
You must be signed in to change notification settings - Fork 1k
fix(storage): bound the cold Codex log inspection and surface when it is skipped (#2605) #2627
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,9 @@ import { | |
|
|
||
| const IMMUTABLE_READONLY_FLAGS = constants.SQLITE_OPEN_READONLY | constants.SQLITE_OPEN_URI; | ||
| const KNOWN_LOG_LEVELS = new Set(["TRACE", "DEBUG", "INFO", "WARN", "ERROR"]); | ||
| // The issue reporter measured a ~1 GB database taking 17.3s for GROUP BY level | ||
| // alone; skipping all row aggregates above 64 MiB reduced /api/storage to 628ms. | ||
| const MAX_SYNCHRONOUS_METRICS_DATABASE_BYTES = 64 * 1024 * 1024; | ||
|
|
||
| interface CurrentLogColumn { | ||
| name: string; | ||
|
|
@@ -115,6 +118,10 @@ export interface CodexLogGuardInspection { | |
| reclaim: CodexLogGuardCapability; | ||
| }; | ||
| metrics: CodexLogGuardMetrics | null; | ||
| metricsSkipped: null | { | ||
| reason: "database_too_large"; | ||
| thresholdBytes: number; | ||
| }; | ||
| } | ||
|
|
||
| interface ColumnRow { | ||
|
|
@@ -167,9 +174,8 @@ function fileSize(path: string): number { | |
| * repeated stalls without ever serving stale numbers: any write changes the WAL | ||
| * and invalidates the entry. | ||
| * | ||
| * This bounds the repeat cost, not the first one. A cold inspection of a huge | ||
| * database still blocks; moving that work off-thread needs a Worker and is | ||
| * tracked separately. | ||
| * Memoization bounds repeat cost. The database-size gate below separately bounds | ||
| * cold request-thread work by omitting these aggregates for large databases. | ||
| */ | ||
| type InspectionCacheEntry = { | ||
| key: string; | ||
|
|
@@ -233,6 +239,7 @@ function unavailableInspection(): CodexLogGuardInspection { | |
| reclaim: unavailable, | ||
| }, | ||
| metrics: null, | ||
| metricsSkipped: null, | ||
| }; | ||
| } | ||
|
|
||
|
|
@@ -425,6 +432,7 @@ function inspectCodexLogsUncached(deps: CodexSqliteHomeDeps = {}): CodexLogGuard | |
| ...common, | ||
| schema, | ||
| metrics: null, | ||
| metricsSkipped: null, | ||
| capabilities: { | ||
| inspection: { state: "supported" }, | ||
| protection: mutation, | ||
|
|
@@ -440,6 +448,7 @@ function inspectCodexLogsUncached(deps: CodexSqliteHomeDeps = {}): CodexLogGuard | |
| ...common, | ||
| schema, | ||
| metrics: null, | ||
| metricsSkipped: null, | ||
| capabilities: { | ||
| inspection: { state: "supported" }, | ||
| protection: mutation, | ||
|
|
@@ -458,6 +467,7 @@ function inspectCodexLogsUncached(deps: CodexSqliteHomeDeps = {}): CodexLogGuard | |
| ...common, | ||
| schema, | ||
| metrics: null, | ||
| metricsSkipped: null, | ||
| capabilities: { | ||
| inspection: { state: "supported" }, | ||
| protection: mutation, | ||
|
|
@@ -476,10 +486,17 @@ function inspectCodexLogsUncached(deps: CodexSqliteHomeDeps = {}): CodexLogGuard | |
| ? { state: "compatible" } | ||
| : { state: "unsupported", reason: "unknown_schema" }; | ||
| const mutation = capabilityFor(schema); | ||
| const metricsSkipped = files.databaseBytes > MAX_SYNCHRONOUS_METRICS_DATABASE_BYTES | ||
| ? { | ||
| reason: "database_too_large" as const, | ||
| thresholdBytes: MAX_SYNCHRONOUS_METRICS_DATABASE_BYTES, | ||
| } | ||
| : null; | ||
| return { | ||
| ...common, | ||
| schema, | ||
| metrics: readMetrics(db, columns), | ||
| metrics: metricsSkipped === null ? readMetrics(db, columns) : null, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
For every compatible database above 64 MiB, this sets the entire Useful? React with 👍 / 👎. |
||
| metricsSkipped, | ||
|
Comment on lines
+498
to
+499
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When a database crosses this threshold, Useful? React with 👍 / 👎. |
||
| capabilities: { | ||
| inspection: { state: "supported" }, | ||
| protection: mutation, | ||
|
|
@@ -496,6 +513,7 @@ function inspectCodexLogsUncached(deps: CodexSqliteHomeDeps = {}): CodexLogGuard | |
| ...common, | ||
| schema, | ||
| metrics: null, | ||
| metricsSkipped: null, | ||
| capabilities: { | ||
| inspection: { state: "supported" }, | ||
| protection: mutation, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This new visible string is added to the bespoke
log-guard-labels.tsmap rather than tosrc/i18n/en.tsand every locale module, and the component renders it throughlogGuardLabelinstead oft(). That bypasses the repository's canonicalTKeytyping and automatic locale discovery, allowing this copy to drift outside the normal i18n validation path; add a standard locale key and render it throught("key").AGENTS.md reference: gui/AGENTS.md:L14-L18
Useful? React with 👍 / 👎.