decompose review-004 recorded findings: 15 disposition tasks + the review-004-fixes gate (sqlite seam panic-safety, watcher-death subscribe + initial-stat, bridge alignment, scheduler classification, substrate SAFETY delta; pg forwarder hardening + diagnosability, BIGINT stamp decision + fix, log-facade decision; core offset pin + Display forging, mem doc notes, pg identifier note, tokio dev-dep normalization) — taskgraph validate green (95)
This commit is contained in:
1 parent
029f885aa1
commit
9bbe645558
16 files changed
+1131
No files matched your search
@@ -0,0 +1,93 @@
|
||||
---
|
||||
id: pg-fix-forwarder-hardening
|
||||
name: Forwarder TOCTOU restructure + hang-shaped arms (review 004 items 4+6)
|
||||
status: pending
|
||||
depends_on: []
|
||||
scope: broad
|
||||
risk: high
|
||||
impact: component
|
||||
level: implementation
|
||||
tags: [review-004-fixes, postgres-engine, forwarder]
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
Forwarder surgery that should ride its own session, per
|
||||
`docs/reviews/004-pre-release-general-review.md` §"Findings recorded,
|
||||
not fixed" items 4 and 6 (the review bundles them as the
|
||||
forwarder-hardening session). Line refs are as of the review; the
|
||||
inline fixes may have shifted them slightly — re-locate on pickup.
|
||||
|
||||
**(a) Register/unregister TOCTOU (item 4).** The registry refcount and
|
||||
the LISTEN/UNLISTEN command emission are not one critical section
|
||||
(`forwarder.rs:131-176` vs `438-482`): interleaved register/unregister
|
||||
across tasks can leave a live refcount with the server-side LISTEN
|
||||
cleared (both queued commands share a generation, so no stale check
|
||||
saves it) until the next reconnect re-issue. Fix shape: a
|
||||
decide-and-queue restructure inside the forwarder — the
|
||||
register/unregister decision and the derived command enqueue must be
|
||||
atomic with respect to each other (decide under the registry guard;
|
||||
queue the command *with* the refcount state it was derived from).
|
||||
|
||||
**(b) Generation-verify/LISTEN failure parks forever (item 6, arm 1).**
|
||||
A failed generation-verify/LISTEN batch is treated as connection death
|
||||
and parks on `poll_task.await` forever even though the session may be
|
||||
alive (`forwarder.rs:698-702/803-808`).
|
||||
|
||||
**(c) Shutdown can leak the listener session (item 6, arm 2).**
|
||||
`close()`/`Drop` can leak the listener session past shutdown when the
|
||||
serve loop is awaiting a command on a black-holed connection (the
|
||||
`run_command` await sits outside the shutdown `select`, `:781`; no
|
||||
timeout on this connection).
|
||||
|
||||
Treatment family for (b)+(c): timeouts/bounded waits on the listener
|
||||
path.
|
||||
|
||||
**Preserve while restructuring** (the gate will check these): the two
|
||||
POC-pinned deadlock pitfalls stay structurally excluded; the reconnect
|
||||
invariants from `pg-fix-forwarder-reconnect` (the retry core, the
|
||||
fanout release guard, receivers-terminal-iff-loop-gone) stay green;
|
||||
the register-failure unregister fix from review 004 (inline fix 3)
|
||||
stays; the poison-recovery lock idiom from review 004 (inline fix 4)
|
||||
stays.
|
||||
|
||||
Use the existing test-seam vocabulary (the reconnect-config slot, the
|
||||
connector injection, the generation tests) for the new pins.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [ ] The TOCTOU is closed: register/unregister interleavings across
|
||||
tasks cannot leave a live refcount with the server-side LISTEN
|
||||
cleared — pinned by a test that interleaves the two and asserts
|
||||
the server-side LISTEN state matches the refcount
|
||||
- [ ] A failed generation-verify/LISTEN batch no longer parks forever:
|
||||
bounded wait with an honest error or reconnect — pinned by test
|
||||
- [ ] `close()`/`Drop` reclaims the listener session even when the
|
||||
serve loop is stuck awaiting on a dead connection — pinned by
|
||||
test (black-holed connection seam)
|
||||
- [ ] The preserved postures listed above re-verified green (existing
|
||||
forwarder pins: reconnect survival, no-replay, shutdown close,
|
||||
stale-UNLISTEN generation tests, the register-failure
|
||||
unregister pin)
|
||||
- [ ] `cargo test -p alkstore-postgres` (harness server), clippy
|
||||
`-D warnings`, fmt clean; workspace gates green server-less
|
||||
|
||||
## References
|
||||
|
||||
- docs/reviews/004-pre-release-general-review.md §"Findings recorded,
|
||||
not fixed" items 4 and 6 (the findings, the fix shapes, the
|
||||
own-session scoping)
|
||||
- docs/architecture/decisions/004-postgres-driver.md (the forwarder's
|
||||
owned failure modes, the two POC-pinned deadlock pitfalls)
|
||||
- tasks/pg-fix-forwarder-reconnect.md (the retry core, the fanout
|
||||
guard, the test-seam vocabulary)
|
||||
- tasks/pg-fix-stale-unlisten.md (the generation/staleness machinery
|
||||
the TOCTOU restructure must compose with)
|
||||
|
||||
## Notes
|
||||
|
||||
> To be filled by implementation agent
|
||||
|
||||
## Summary
|
||||
|
||||
> To be filled on completion
|
||||
Reference in new issue
Block a user