M9: leaving a live session sends what was waiting its turn

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
fluid-chey
2026-11-04 13:03:09 -07:00
co-authored by Claude Opus 5.5
parent 436b893741
commit e87078a8ec
4 changed files with 24 additions and 1 deletions
+6
View File
@@ -339,6 +339,12 @@ impl<S: Socket> Driver<S> {
/// Leave the session.
pub(crate) fn leave(&mut self, now: Instant) {
// What you did before leaving still reaches the others, whatever its turn.
while let Some((_, msg)) = self.paced.pop_front() {
if !self.write(&msg) {
break;
}
}
self.end(Outcome::Left, now);
}
+15
View File
@@ -392,6 +392,21 @@ fn a_long_queue_goes_out_paced_and_in_order() {
assert_eq!(d.deadline().unwrap() - now, ms(500), "nothing left to send but the reconnect");
}
#[test]
fn leaving_sends_what_was_waiting_its_turn() {
let t0 = Instant::now();
let (mut d, _inbox) = start(Script::default(), t0);
d.opened(t0);
d.message(&welcome(), t0);
for seq in 0..300 {
d.send(ClientMsg::Ack { seq }, t0);
}
d.leave(t0);
let seqs: Vec<u64> = d.sock.sent.iter().filter_map(|m| if let ClientMsg::Ack { seq } = m { Some(*seq) } else { None }).collect();
assert_eq!(seqs, (0..300).collect::<Vec<u64>>());
assert!(d.done());
}
#[test]
fn a_first_join_that_cant_reach_the_host_fails_at_once() {
let t0 = Instant::now();
+2
View File
@@ -306,6 +306,8 @@ fn session(
}
Ok(Cmd::Lost(e, o)) if e == epoch => break o,
Ok(Cmd::Leave) | Err(RecvTimeoutError::Disconnected) => {
// What you did before leaving still reaches the others, whatever its turn.
while paced.pop_front().is_some_and(|(_, m)| send(&mut writer, &m)) {}
let _ = writer.close(Some(CloseFrame { code: CloseCode::Normal, reason: "".into() }));
break Outcome::Left;
}
+1 -1
View File
@@ -26,7 +26,7 @@ cursors, selections, text carets, cursor chat and spotlights shown live ([`colla
| Date | Change | Summary |
|---|---|---|
| 2026-11-04 | minor | M9: a session you joined no longer turns into a local file by itself. A dropped connection reconnects until you leave (a minute's pause after each 12 attempts, a pause Retry now skips); only refusals that are for good stop it; queued messages go out paced. While disconnected the tab shows a red mark and a strip across the canvas says so; a session that ended stays on its tab with Try again, Save a copy and Dismiss, and what changed offline opens beside it when it joins again |
| 2026-11-04 | minor | M9: a session you joined no longer turns into a local file by itself. A dropped connection reconnects until you leave (a minute's pause after each 12 attempts, a pause Retry now skips); only the host ending the session and refusals that are for good stop it; queued messages go out paced. While disconnected the tab shows a red mark and a strip across the canvas says so; a session that ended stays on its tab with Try again, Save a copy and Dismiss, and what changed offline opens beside it when it joins again |
| 2026-10-31 | patch | M9, #1665: the document in a live session's welcome goes compressed (deflate) to clients whose hello announces `packed`, about seven times smaller on the wire (a synthetic file of 4,040 layers: 397 KB to 53 KB); older clients keep getting it uncompressed, and the client reads a packed document only up to the size an uncompressed welcome could have had. |
| 2026-10-30 | minor | M9, part of #742: a team list on `figcraft-server`. With `team_files = "edit"` (or `comment`, `view`) everyone who reaches the server sees the files shared from it now (a link of theirs has a join code: Share ▸ Start sharing) and joins them by a team list link, `figcraft://join?server=…&file=…&team=1`, which carries no secret: the server hands out the file's team link while it stays shared (`ResolveTeam`, answered like a join code), and Stop sharing revokes it with the others, disconnecting whoever joined with it. Turning the list off or changing its access refuses the old team links at once. `collab.files {refresh}` asks the server in Preferences for its list (`Admin::Team`; not the public server FigCraft ships with), and Home ▸ Online shows it below your own files: a row joins its file, its menu copies the link for the app or, with the server's `web_url`, for the browser build (`<web_url>#join=…`). A browser build served beside its server names it with `<meta name="figcraft-server">`, the page's default for sharing, codes and the team list. No accounts: the list is for a server only your team reaches. Tests: `team_tests` (the server and apps over loopback), `code_tests` (links and the browser's driver), `online_tests` (the Online section), `query_tests` (the page's server). Percentages and hours unchanged |
| 2026-10-30 | minor | M9, #1130: `figcraft-server` compares the SHA-256 digests of the presented and the kept server key instead of the raw strings, as `docs/server.md` says; the key file, `figcraft-server key` and rotation are unchanged. Numbers unchanged. |