feat(host): liveRows hands out a wait for a write's transaction on its followed read
First step of the txid rollout from Neon's mutations guide (https://neon.com/docs/ai/skills/neon-realtime/references/mutations.md): a write returns pg_current_xact_id()::text from its own RETURNING, and the host waits with awaitTxId(txid, timeout) on the subscription that shows it. This PR only adds the shared wait in liveRows. Each area's writes come in their own PRs.
Reworks #4230 (TxWait, branch luke/live-tx-wait) onto today's main, after #4403's shared client.
What changes
-
liveRowshands its caller aTxWaitthroughonTxWaitonce every part of a read followed over Realtime is live. The wait settles when the transaction reaches any of the read's parts, since a write only reaches the parts whose rows it changes. The wait is taken back (undefined) when the subscriptions are let go, including when the read falls back to polling. -
confirmWrite(wait, txid)waits up to 10 s. It confirms at once when:- the write changed no row (no txid);
- the read has no Realtime wait (polled, or not live yet), since the next poll shows the write anyway.
On a timeout it logs and confirms anyway, because the write committed.
-
The test fakes gain
awaitTxId. The sharedtesting/fake-realtime.tsgetsarrive(txid)andawaitingTxids()for the area PRs' tests.
Tests
live-follow.test.ts:
- the wait is handed out only once every part is live, is settled by the part the write reaches, and is taken back once the read is let go;
- a read that falls back to polling has no wait, so a write confirms without hanging;
- a no-op write (no txid) confirms at once, and a committed one waits until its txid arrives;
- a txid that never arrives is still confirmed after 10 s.
Made with Luke