Skip to content

Finalize remote Huddles only on explicit leave; treat archived as terminal - #9384

Merged
brow merged 1 commit into
terp/huddle-relay-ending-20261111from
fix-9376-remote-huddle-ending
Nov 13, 2026
Merged

brow merged 1 commit into
terp/huddle-relay-ending-20261111from
fix-9376-remote-huddle-ending

Conversation

@brow

@brow brow commented Nov 12, 2026

Copy link
Copy Markdown
Collaborator

Stacked on #9376 remote Huddle cleanup. It fixes two blocking findings from review of 04321aa.

Summary

Only an explicit leave ends a remote Huddle. On 04321aa, when a control stream ended with peers still registered, the owner archived the channel and published the ended event (48103). That happens when the ingress relay restarts (Huddle audio sockets aren't drained, so they never send UnregisterPeer), crashes, or loses its relay-to-relay link. The ingress tells its clients to rejoin, but the rejoin then finds the channel archived. Now only an UnregisterPeer frame finalizes the room. Loop-exit teardown goes back to main's behavior: it removes the room and releases the lease, without ending the Huddle. On the ingress, a SessionEnded teardown (the local client's control sink closed while a roster update was queued) now sends the clean close first, so a real leave that loses the reader's select race still unregisters.

An already-archived channel is a terminal outcome. The mobile end flow archives the channel itself, often before the last remote connection closes. archive_channel_if returned "channel is already archived" as an error, so the finalizer kept the empty room and its renewing lease with no retry. It now returns Ok(false) when the locked row is already archived. The finalizer then releases local resources and publishes no second ended event. This also fixes main's equivalent leak on the local path.

Out of scope, per review: retrying after a failed archive, the Redis validation inside the archive transaction, and the draining-owner behavior change.

Related issue

N/A. Review findings on #9376 remote Huddle cleanup.

Testing

  • remote_last_leave_ends_huddle_and_releases_owner_resources (new Postgres journey, runs in the postgres-ci lane with Redis): the owner's local participant leaves, then the last remote participant leaves cleanly through the production HuddleControlAcceptor and finalizer. The unarchived row ends the Huddle once. The creator-archived row publishes no relay ending. Both rows release the room and lease.
  • remote_only_stream_close_releases_owner_room_and_lease now covers both a bare stream drop (room and lease released, no ending) and a clean leave (exactly one ending).
  • conditional_archive_rechecks_authority_before_committing asserts that archiving an already-archived channel returns Ok(false).
  • Ran each guard both ways: removing the already-archived early return fails the creator-archived row and the DB test, and letting stream loss finalize fails the bare-drop row.
  • Full non-ignored buzz-relay and buzz-db suites pass, and clippy is clean. Not validated on a live multi-relay call.

🤖 Generated with Claude Code

…minal

A control stream that ends with peers still registered means the ingress
relay restarted, crashed or lost its mesh link, and its clients are told
to rejoin. Archiving there refused the rejoin. Only an UnregisterPeer
frame now finalizes the room; loop-exit teardown releases the room and
lease without ending the Huddle, as main did. The ingress also sends its
clean close when a SessionEnded teardown wins the reader's select, so a
real leave still unregisters.

archive_channel_if returns Ok(false) when the locked row is already
archived (the mobile end flow archives first), so the finalizer releases
the empty room and its lease instead of retaining them with no retry.

Co-authored-by: studio <dc2fc481343672df31a689840c09299972e704dac592e0da6f18486646a7ee3e@buzz.block.builderlab.xyz>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Signed-off-by: Tom Brow <[email protected]>
@brow

brow commented Nov 12, 2026

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 12, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-12T05:00:15.795511Z 8fd316b Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Another round soon, please!

Reviewed commit: 8fd316b2c9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@brow
brow marked this pull request as ready for review November 12, 2026 04:58
@brow
brow requested a review from a team as a code owner November 12, 2026 04:58
@brow
brow merged commit 5221467 into terp/huddle-relay-ending-20261111 Nov 13, 2026
82 checks passed
@brow
brow deleted the fix-9376-remote-huddle-ending branch November 13, 2026 00:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants