mirror of
https://github.com/block/buzz.git
synced 2026-10-31 06:21:34 +00:00
A relay drain (SIGTERM or owner-drain) cancelled every local owner client at once, so the last teardown emptied the room and took the archive + 48103 path: every pod restart ended every huddle it owned. The same path also ended a huddle the instant its last client blipped, so a reconnect found the channel archived. The leave path now distinguishes a drain-driven teardown (the owner draining token fired, or `shutting_down` / `owners.is_draining()` is set, covering single-pod mode where there is no mesh token) and only releases the lease and drops the empty room, leaving the channel alive for rejoiners to re-acquire through Redis. Ordinary last-leaver departures no longer end the room atomically. `remove_peer_and_check_idle` captures an `IdleGeneration` (the admission count) under the guard lock; a spawned task waits `ROOM_EMPTY_GRACE` and calls `end_if_idle`, which sets `ended` only if the room is still empty and no admission happened in between. A rejoin during the window fences the stale observation even if the rejoiner has already left again, and two leavers who both observed empty cannot both archive. Owner-loss or a drain that begins mid-window aborts the end; owner-loss wins a tie with the timer. The fence only holds if the rejoiner lands on the same `Room`. A pre-last leaver's `cleanup_if_empty` (or a failed pre-admission join) could run after the last leaver's idle observation and evict the empty room from the manager; the rejoiner would then get a fresh `Room` and the stale grace task would archive underneath it. The idle observation now sets `idle_hold` on the room and `cleanup_if_empty` refuses to evict while it is set. The hold survives `end_if_idle` so the room stays registered while `archive_channel` is in flight — a joiner in that gap meets `ended` on the same room instead of admitting into a fresh one whose pre-join DB check raced the archive. The hold clears on admission or via the fenced `release_idle_hold`, called after the archive resolves (success or rollback) and on the drain/abort paths that abandon the window. Tests: room idle generation (last-leaver-only, end-once, rejoin fences stale), manager eviction (concurrent-leaver ordering pins the room and the rejoiner fences the stale end; released hold permits eviction, stale release does not; ended room stays pinned and refuses joiners until the archive resolves; failed archive reopens and releases), and paused-time grace outcomes (holds through window, rejoin, no-rejoin ends, owner-loss aborts, mid-window drain aborts). Co-authored-by: Meli <5aaa86bce934fc3445fc254aab560a40923f10252f92107e665073dede0e04d3@buzz.block.builderlab.xyz> Signed-off-by: Meli <5aaa86bce934fc3445fc254aab560a40923f10252f92107e665073dede0e04d3@buzz.block.builderlab.xyz>