M9: a joined live session keeps reconnecting and says when it's disconnected

A session you joined could end for reasons that pass, or after about 85 s of
retries, and its tab then looked like an unsaved local file. Work done there
reached no one, with only a 3 s toast to say so.

A live connection now reconnects until you leave, pausing a minute after each
12 attempts. Only refusals that are for good stop it, so "too many messages",
"busy" and the like retry. Messages queued while offline go out paced so a long
queue can't trip the server's rate limit. A session that ended stays on its tab:
the tab shows a red mark and a strip across the canvas offers Retry now or Try
again, Save a copy and Dismiss. Joining again uses the same tab, and what changed
offline opens beside it as an unsaved copy. A session that gets out of step
joins again by itself.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
fluid-chey
2026-11-04 12:17:25 -07:00
co-authored by Claude Opus 5.5
parent 6f780211dd
commit fccaa43101
30 changed files with 687 additions and 59 deletions
+15 -3
View File
@@ -535,9 +535,21 @@ resuming with its offline edits, and leaving the session going back to snapshot
`ws://<ip:port>/` and sends the token only inside its `Hello`. Links are pasted into the Join
dialog (its field has the keyboard when it opens; Escape closes it), or opened from anywhere:
see *Opening invite links* below.
- Reconnect: a connection that drops after it was live reconnects with growing pauses (0.5 s,
doubling up to 10 s, 12 attempts); a refusal (wrong token, full) or the host ending the session
is final; a first join that can't reach the host fails at once. A reconnect resumes as the same
- Reconnect: a connection that drops after it was live reconnects until you leave, with growing
pauses (0.5 s, doubling up to 10 s, 12 attempts), then a minute's pause and as many again. A
server turning a live session away is taken as passing (busy, a limit, a file it couldn't read
just now) unless it says why in words that are for good: the link, the file or your place in it
is gone, or the versions can't talk (`FINAL_REFUSALS` in `crates/collab-net/src/join.rs`). Those
and the host ending the session are final; a first join that can't reach the host fails at once.
Messages queued while offline go out paced, so they stay within what a server takes from a
connection.
- Disconnected: while it reconnects, and after it can't go on, the tab shows a red mark and a strip
across the top of the canvas says so, with **Retry now** (`collab.reconnect`). The tab can still
be edited. A session you joined that ended stays on its tab with **Try again**, **Save a copy…**
and **Dismiss** (`collab.leave`). **Try again** joins it in the same tab as someone new; if the
tab changed since it lost the server, what changed opens beside it as an unsaved
"offline copy" and the tab shows the server's version. A session that gets out of step does the
same by itself. A reconnect resumes as the same
client: the guest's connection keeps the session id, client id and last sequence number from
the messages it read and sends them in its next `Hello` (see Offline and reconnect).
- The browser build joins and publishes to a server (see *Built (the browser client)*); hosting