mirror of
https://github.com/Twigpine/node.git
synced 2026-11-10 05:01:48 -10:00
The post-receive tail was spawned after `guard.release(...)`, which on a successful push awaits the Tigris upload and then the advisory unlock while the handler future is still tied to the client connection. The pack has already landed on disk by then, so a disconnect in that window left a durable push whose pins, recovery copy and announce were never spawned: the dropped tail F2 closed, one step earlier in the handler. Spawn it above `release`, gated on an explicit `receive_result.is_ok()`. The `?` below the spawn can no longer be what keeps a rejected push from pinning and announcing a half-applied repo, so the success check is now a named flag that `release` consumes too. The tail is read-only on the repo directory and holds neither the lease nor the advisory lock, so overlapping it with the upload waits on nothing the handler still owns. Tests: a handler-level disconnect driven through a parked `release` (new store-level test seam), plus the must-not direction, a failed receive-pack that spawns no tail. The U5 source gate now binds the new boundary: spawn inside `if push_succeeded`, above `guard.release(push_succeeded)`.