pg tx producer paths wake commit-atomically: publish_with_key_tx/enqueue_tx/outbox_enqueue_tx issue pg_notify on their mechanism-named channel (stream name / queue name / derived backing queue) inside the caller's tx — empty payload, best-effort log-and-swallow, no double-wake on the auto-commit paths; shared tx::wake_tx owner + module-doc section pinning the semantics; new tx_tests harness test pinning pre-commit silence, commit delivery on all three channels, and rollback silence; F-1 engine arm retired in review-wave-4 + implementation.md records (tx_publishes_compose_with_the_handle deterministic: 20 solo runs green; pg suite 116/116 x2 vs harness) (task pg-fix-tx-wake, review 002 Finding 2)
This commit is contained in:
1 parent
7ae426a01d
commit
9a5d1f4705
5 files changed
+261
-15
No files matched your search
+57
-3
@@ -1,7 +1,7 @@
|
||||
---
|
||||
id: pg-fix-tx-wake
|
||||
name: Fix tx enqueue/publish paths issuing no pg_notify wake (review 002 Finding 2 — F-1's root cause)
|
||||
status: pending
|
||||
status: completed
|
||||
depends_on: []
|
||||
scope: narrow
|
||||
risk: low
|
||||
@@ -98,8 +98,62 @@ review-rounds line for the general review.
|
||||
|
||||
## Notes
|
||||
|
||||
> To be filled by implementation agent
|
||||
Fix-shape decisions of record (what the description left open):
|
||||
|
||||
- **One-owner wake statement**: all three producer paths call a
|
||||
shared `tx::wake_tx(client, channel)` — `SELECT pg_notify($1, '')`
|
||||
(empty payload, `Wake { channel }` only per ADR-008 §3) issued on
|
||||
the caller's tx client after the INSERT. Channel = the stream name
|
||||
(`publish_tx` rides `publish_with_key_tx`, so one site), the queue
|
||||
name (`enqueue_tx`), and the outbox's derived `__alkstore_outbox:{name}`
|
||||
(`outbox_enqueue_tx`).
|
||||
- **Wake error posture**: best-effort log-and-swallow (the engine-wide
|
||||
stance — a wake must never fail a write), matching the auto-commit
|
||||
publish/enqueue twins. Documented hazard: a failed statement aborts
|
||||
the pg tx server-side, so a swallowed wake failure still surfaces
|
||||
typed at COMMIT — no silent half-state; a rolled-back tx's queued
|
||||
notifies are discarded server-side with the row (the no-ghosts arm
|
||||
is native).
|
||||
- **No double-wake**: the wake is applied at the tx call sites, NOT
|
||||
inside the shared `enqueue_row`/INSERT — the auto-commit
|
||||
`Queue::enqueue` and the scheduler's fire-wake keep their own single
|
||||
statements on their pool connections, untouched.
|
||||
- **`run_once` untouched** (pull op, consumer-driven — no wake, per
|
||||
the task).
|
||||
- **Test shape**: one harness test in `tx_tests.rs`
|
||||
(`tx_producer_wakes_are_commit_atomic_and_rollback_discards_them`)
|
||||
pins all four arms — pre-commit silence (commit-atomic, not
|
||||
statement-atomic: 300 ms statement window + 100 ms listen, then
|
||||
commit), deterministic wake delivery at commit on all three
|
||||
registered channels, rollback silence, committed row-count truth.
|
||||
Uses `forwarder().register` + the raw fanout (`listener_hears`);
|
||||
`register` does no name validation, so the reserved derived outbox
|
||||
channel registers directly.
|
||||
- **Record updates went slightly beyond the strict line**: besides
|
||||
the review-rounds line, `docs/plans/implementation.md`'s frontmatter
|
||||
`last_updated` and the wave-4 gate bullet's "root cause unresolved"
|
||||
text got dated supersede/correction pointers (the stale-reference
|
||||
discipline — those conclusions were factually wrong, not just
|
||||
unresolved).
|
||||
|
||||
## Summary
|
||||
|
||||
> To be filled on completion
|
||||
**Landed**: the tx producer paths' commit-atomic `pg_notify` wakes
|
||||
(`tx.rs`: `wake_tx` helper + the three call sites + the "The tx wakes"
|
||||
module-doc section pinning the semantics) — `publish_with_key_tx`/
|
||||
`publish_tx` (the contract obligation: streams never require polling;
|
||||
rollback drops the row with its wake) and the posture-parity
|
||||
`enqueue_tx`/`outbox_enqueue_tx` twins (channel = queue name / derived
|
||||
backing queue); the new pinned tx-wake test; the F-1 retirement
|
||||
recorded in `tasks/review-wave-4.md` (including the correction that
|
||||
the gate's "the tx INSERT's commit *is* the NOTIFY carrier" conclusion
|
||||
was wrong) and `docs/plans/implementation.md`.
|
||||
|
||||
**Verified**: full pg lib suite 116/116 green against the harness
|
||||
server (two consecutive full runs, ~70 s each); the new wake test
|
||||
green; `tx_publishes_compose_with_the_handle` deterministic — 20
|
||||
consecutive solo runs green with zero deadline misses; workspace
|
||||
`cargo test` server-less green (harness tests skip cleanly);
|
||||
`cargo clippy --all-targets -- -D warnings` clean; `cargo fmt --check`
|
||||
clean. Auto-commit publish/enqueue unchanged (their wake tests ride
|
||||
the suite untouched).
|
||||
Reference in new issue
Block a user