Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 17 additions & 9 deletions src/lib/snapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,21 +139,27 @@ export async function readSnapshot(
signal: AbortSignal.timeout(2_000),
},
);
if (!res.ok) return null;
if (!res.ok) {
console.warn(`[DRAFT-TRACE] kv_http slug=${slug} status=${res.status}`);
return null;
}
const env = (await res.json()) as { result?: string | null };
if (!env.result) return null;
if (!env.result) {
console.warn(`[DRAFT-TRACE] kv_empty slug=${slug} (no snapshot ever written)`);
return null;
}
const raw = JSON.parse(env.result);
const parsed = SnapshotSchema.safeParse(raw);
if (!parsed.success) {
console.warn(
`snapshot.read rejected (shape) for ${slug}: ${parsed.error.message}`,
`[DRAFT-TRACE] kv_shape slug=${slug} err=${parsed.error.message}`,
);
return null;
}
const age = Date.now() - parsed.data.savedAt;
if (age > MAX_SNAPSHOT_AGE_MS) {
console.warn(
`snapshot.read rejected (stale ${Math.round(age / 1000 / 60)}m) for ${slug}`,
`[DRAFT-TRACE] kv_stale slug=${slug} age_min=${Math.round(age / 1000 / 60)}`,
);
return null;
}
Expand All @@ -164,11 +170,13 @@ export async function readSnapshot(
lastRunAt: parsed.data.lastRunAt,
};
} catch (err) {
console.warn(
`snapshot.read failed for ${slug}: ${
err instanceof Error ? err.message : String(err)
}`,
);
const msg = err instanceof Error ? err.message : String(err);
// Distinguish abort/timeout (most common) from other network errors so
// the post-incident grep can see if it's KV slowness vs KV down.
const tag = msg.toLowerCase().includes("abort") || msg.toLowerCase().includes("timeout")
? "kv_timeout"
: "kv_neterr";
console.warn(`[DRAFT-TRACE] ${tag} slug=${slug} err=${msg}`);
return null;
}
}
Expand Down
22 changes: 22 additions & 0 deletions src/lib/spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ const loadBenchmarkUnfilteredCached = unstable_cache(
const specs = await loadSpecs();
const spec = specs.find((s) => s.slug === slug);
if (!spec) return undefined;
const promStart = Date.now();
const bench = await specToBenchmark(spec);
const promMs = Date.now() - promStart;
if (spec.status === "live" && bench.status === "draft") {
// Live spec, but Prom returned nothing this cycle. Try the
// persistent snapshot before giving up. This is the cold-start
Expand All @@ -51,8 +53,18 @@ const loadBenchmarkUnfilteredCached = unstable_cache(
// good data; without KV we throw to preserve any previous cache
// value (or eventually fall through to the draft placeholder in
// the aggregator).
// [DRAFT-TRACE] temporary observability — remove once we've pinned
// the cause of intermittent draft renders.
console.warn(
`[DRAFT-TRACE] collapse slug=${slug} prom_ms=${promMs} → trying KV snapshot`,
);
const kvStart = Date.now();
const snap = await readSnapshot(slug);
const kvMs = Date.now() - kvStart;
if (snap) {
console.warn(
`[DRAFT-TRACE] kv_hit slug=${slug} kv_ms=${kvMs} → serving snapshot`,
);
const editorial = buildEditorial(spec);
const reconstructed = renderBenchmarkText({ ...editorial, ...snap });
// The reconstructed bench is live data, just sourced from KV
Expand All @@ -63,6 +75,9 @@ const loadBenchmarkUnfilteredCached = unstable_cache(
}
return reconstructed;
}
console.warn(
`[DRAFT-TRACE] kv_miss slug=${slug} kv_ms=${kvMs} → throwing to keep prev cache`,
);
throw new Error(
`loadBenchmark(${slug}): live spec collapsed to draft, keeping prev cache`,
);
Expand Down Expand Up @@ -99,6 +114,13 @@ const loadAllBenchmarksCached = unstable_cache(
// to. Surface a placeholder so the page still renders rather
// than dropping the bench from the list (which would break the
// sitemap, the products pages, and the "More benchmarks" rail).
// [DRAFT-TRACE] this is the path that produces a visible "draft"
// render to the user — log so we can correlate with KV / prom state.
const reason =
r.status === "rejected" ? (r.reason instanceof Error ? r.reason.message : String(r.reason)) : "no_value";
console.warn(
`[DRAFT-TRACE] placeholder_used slug=${spec.slug} reason=${reason}`,
);
benchmarks.push(draftPlaceholderForSpec(spec));
}
}
Expand Down
Loading