Merge pull request #2111 from pikasTech/fix/2109-db-write-readiness
fix: 分离 Postgres 写入 readiness 与 durable read readiness
This commit is contained in:
@@ -966,6 +966,37 @@ test("configured postgres runtime allocates Workbench projectedSeq idempotently
|
||||
assert.ok(queryClient.calls.some((call) => call.sql.startsWith("SELECT pg_advisory_xact_lock")));
|
||||
});
|
||||
|
||||
test("configured postgres runtime writes Workbench facts without re-running blocked read readiness", async () => {
|
||||
const queryClient = createFakePostgresClient({ migrationReady: true, countErrorCode: "53300" });
|
||||
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-25T02:50:00.000Z"
|
||||
});
|
||||
|
||||
const readiness = await store.readiness();
|
||||
assert.equal(readiness.blocker, RUNTIME_DURABLE_ADAPTER_QUERY_BLOCKED);
|
||||
assert.equal(readiness.connection.queryResult, "query_blocked");
|
||||
queryClient.calls.length = 0;
|
||||
|
||||
const write = await store.writeWorkbenchFacts({
|
||||
facts: {
|
||||
sessions: [{ sessionId: "ses_write_after_read_blocked", ownerUserId: "usr_write_after_read_blocked", status: "running", updatedAt: "2026-06-25T02:50:01.000Z" }]
|
||||
}
|
||||
});
|
||||
|
||||
assert.equal(write.written, true);
|
||||
assert.equal(queryClient.calls.filter((call) => isReadinessQuery(call.sql)).length, 0);
|
||||
assert.equal(queryClient.calls.some((call) => call.sql.startsWith("CREATE INDEX IF NOT EXISTS")), false);
|
||||
assert.ok(queryClient.calls.some((call) => call.sql === "BEGIN"));
|
||||
assert.ok(queryClient.calls.some((call) => call.sql === "COMMIT"));
|
||||
assert.ok(queryClient.calls.some((call) => call.sql.startsWith("INSERT INTO workbench_sessions")));
|
||||
});
|
||||
|
||||
test("configured postgres runtime reuses proven readiness for Workbench durable reads", async () => {
|
||||
const queryClient = createFakePostgresClient({ migrationReady: true });
|
||||
const store = createConfiguredCloudRuntimeStore({
|
||||
@@ -982,6 +1013,7 @@ test("configured postgres runtime reuses proven readiness for Workbench durable
|
||||
sessions: [{ sessionId: "ses_ready_cached", ownerUserId: "usr_ready", status: "running", updatedAt: "2026-06-20T10:00:01.000Z" }]
|
||||
}
|
||||
});
|
||||
await store.readiness();
|
||||
queryClient.calls.length = 0;
|
||||
|
||||
const first = await store.queryWorkbenchFacts({ families: ["sessions"], limit: 10 });
|
||||
@@ -1029,6 +1061,7 @@ test("configured postgres runtime can query thin Workbench session summaries", a
|
||||
}]
|
||||
}
|
||||
});
|
||||
await store.readiness();
|
||||
queryClient.calls.length = 0;
|
||||
|
||||
const loaded = await store.queryWorkbenchFacts({ families: ["sessions"], sessionProjection: "summary", limit: 10 });
|
||||
|
||||
@@ -1533,8 +1533,12 @@ export class PostgresCloudRuntimeStore {
|
||||
}
|
||||
|
||||
async assertReadyForWrites() {
|
||||
const readiness = await this.readiness();
|
||||
if (readiness.ready !== true) {
|
||||
if (!this.dbUrl && !this.queryClient) {
|
||||
const readiness = this.blockedSummary({
|
||||
blocker: RUNTIME_DURABLE_ADAPTER_UNCONFIGURED,
|
||||
reason: "Postgres runtime adapter is selected but HWLAB_CLOUD_DB_URL is not injected"
|
||||
});
|
||||
this.lastReadiness = readiness;
|
||||
throw new HwlabProtocolError("Postgres durable runtime adapter is not ready for writes", {
|
||||
code: ERROR_CODES.internalError,
|
||||
data: {
|
||||
|
||||
Reference in New Issue
Block a user