fix(workbench): bound durable read fan-out (#1954)

This commit is contained in:
Lyon
2026-06-23 06:48:49 +08:00
committed by GitHub
parent bcb3a4d02e
commit 0d0fdd0b51
2 changed files with 21 additions and 15 deletions
+9 -7
View File
@@ -582,14 +582,16 @@ async function queryFactsForSessionSummaries(readModel, sessions = []) {
const sessionIds = uniqueText(sessions.map(factSessionId));
const traceIds = uniqueText(sessions.map(factLastTraceId));
if (sessionIds.length === 0 && traceIds.length === 0) return { facts: emptyFactSet(), count: 0, durable: false, persistence: null };
const bySessionPromise = sessionIds.length > 0
? readModel.queryFacts({ sessionIds, families: ["messages", "turns"] })
: Promise.resolve({ facts: emptyFactSet(), count: 0, durable: false, persistence: null });
const byTracePromise = traceIds.length > 0
? readModel.queryFacts({ traceIds, families: ["checkpoints"] })
: Promise.resolve({ facts: emptyFactSet(), count: 0, durable: false, persistence: null });
const [bySession, byTrace] = await Promise.all([bySessionPromise, byTracePromise]);
// Session list summary is hot and is also sampled by the two-page web-probe
// observer. Avoid parallel fan-out here so one list request cannot consume
// multiple durable-read connections while another page is refreshing.
const bySession = sessionIds.length > 0
? await readModel.queryFacts({ sessionIds, families: ["messages", "turns"] })
: { facts: emptyFactSet(), count: 0, durable: false, persistence: null };
if (bySession.error) return bySession;
const byTrace = traceIds.length > 0
? await readModel.queryFacts({ traceIds, families: ["checkpoints"] })
: { facts: emptyFactSet(), count: 0, durable: false, persistence: null };
if (byTrace.error) return byTrace;
const facts = mergeFactSets(bySession.facts, byTrace.facts);
return { facts, count: Object.values(facts).reduce((sum, rows) => sum + rows.length, 0), durable: bySession.durable ?? byTrace.durable, persistence: bySession.persistence ?? byTrace.persistence ?? null };