fix: reuse proven runtime readiness for workbench reads

This commit is contained in:
lyon
2026-06-20 12:17:54 +08:00
parent f41db95dc0
commit c8ff65f11f
3 changed files with 61 additions and 0 deletions
+33
View File
@@ -806,6 +806,33 @@ test("configured postgres runtime persists and queries Workbench durable facts",
assert.ok(queryClient.calls.some((call) => call.sql.startsWith("SELECT session_json FROM workbench_sessions WHERE session_id = $1")));
});
test("configured postgres runtime reuses proven readiness for Workbench durable reads", async () => {
const queryClient = createFakePostgresClient({ migrationReady: true });
const store = createConfiguredCloudRuntimeStore({
env: {
HWLAB_CLOUD_RUNTIME_ADAPTER: "postgres",
HWLAB_CLOUD_RUNTIME_DURABLE: "true"
},
dbUrl: "postgres://hwlab_redacted@db.example.invalid:5432/hwlab",
queryClient,
now: () => "2026-06-20T10:00:00.000Z"
});
await store.writeWorkbenchFacts({
facts: {
sessions: [{ sessionId: "ses_ready_cached", ownerUserId: "usr_ready", status: "running", updatedAt: "2026-06-20T10:00:01.000Z" }]
}
});
queryClient.calls.length = 0;
const first = await store.queryWorkbenchFacts({ families: ["sessions"], limit: 10 });
const second = await store.queryWorkbenchFacts({ families: ["sessions"], limit: 10 });
assert.equal(first.count, 1);
assert.equal(second.count, 1);
assert.equal(queryClient.calls.filter((call) => isReadinessQuery(call.sql)).length, 0);
assert.equal(queryClient.calls.filter((call) => call.sql.startsWith("SELECT session_json FROM workbench_sessions")).length, 2);
});
test("configured postgres runtime queries requested workbench fact families concurrently", async () => {
const expectedReads = 4;
let started = 0;
@@ -930,6 +957,12 @@ test("configured postgres runtime pushes trace event query filters into SQL", as
assert.deepEqual(select.params, ["ses_filter_b"]);
});
function isReadinessQuery(sql) {
return sql.includes("information_schema.columns")
|| sql.startsWith("SELECT id, schema_version FROM hwlab_schema_migrations")
|| sql.startsWith("SELECT COUNT(*)::int AS count FROM ");
}
function createFakePostgresClient({
migrationReady = true,
migrationErrorCode = null,
+7
View File
@@ -1372,7 +1372,10 @@ export class PostgresCloudRuntimeStore {
}
async assertReadyForDurableReads(method) {
const current = this.summary();
if (isReadyForDurableRuntimeRead(current)) return;
const readiness = await this.readiness();
if (isReadyForDurableRuntimeRead(readiness)) return;
if (readiness.ready !== true || readiness.durable !== true || readiness.liveRuntimeEvidence !== true) {
throw durableRuntimeReadBlockedError(method, readiness);
}
@@ -1697,6 +1700,10 @@ export class PostgresCloudRuntimeStore {
}
}
function isReadyForDurableRuntimeRead(readiness = {}) {
return readiness.ready === true && readiness.durable === true && readiness.liveRuntimeEvidence === true;
}
function normalizeCapabilityInputs(params) {
const value = params.capabilities ?? params.capability ?? params;
if (Array.isArray(value)) {