Preserve alternate screen snapshots and speed builds
ci / test (push) Has been cancelled
ci / remote-bench (push) Has been cancelled

This commit is contained in:
DuProcess
2026-06-11 16:19:30 -04:00
parent 93a210b420
commit 1860a0e610
3 changed files with 77 additions and 7 deletions
+5 -3
View File
@@ -27,6 +27,8 @@ vt100 = "0.15"
tempfile = "3.14" tempfile = "3.14"
[profile.release] [profile.release]
codegen-units = 1 opt-level = 2
lto = "thin" codegen-units = 16
strip = true incremental = true
lto = false
strip = false
+15 -4
View File
@@ -277,7 +277,7 @@ async fn handle_bootstrap_attach(
session.parser.set_size(req.rows, req.cols); session.parser.set_size(req.rows, req.cols);
} }
let client_id = crypto::random_16(); let client_id = crypto::random_16();
let snapshot = session.parser.screen().state_formatted(); let snapshot = screen_snapshot(session.parser.screen());
let screen = session.parser.screen().clone(); let screen = session.parser.screen().clone();
let output_seq = session.output_seq; let output_seq = session.output_seq;
session.clients.insert( session.clients.insert(
@@ -385,7 +385,7 @@ async fn handle_ticket_attach(
session.parser.set_size(req.rows, req.cols); session.parser.set_size(req.rows, req.cols);
} }
let client_id = crypto::random_16(); let client_id = crypto::random_16();
let snapshot = session.parser.screen().state_formatted(); let snapshot = screen_snapshot(session.parser.screen());
let screen = session.parser.screen().clone(); let screen = session.parser.screen().clone();
let output_seq = session.output_seq; let output_seq = session.output_seq;
session.clients.insert( session.clients.insert(
@@ -491,7 +491,7 @@ async fn handle_resume(
session.pty.resize(req.cols, req.rows)?; session.pty.resize(req.cols, req.rows)?;
session.parser.set_size(req.rows, req.cols); session.parser.set_size(req.rows, req.cols);
} }
let snapshot = session.parser.screen().state_formatted(); let snapshot = screen_snapshot(session.parser.screen());
client.last_screen = Some(session.parser.screen().clone()); client.last_screen = Some(session.parser.screen().clone());
(client.send_seq, session.output_seq, snapshot) (client.send_seq, session.output_seq, snapshot)
}; };
@@ -675,7 +675,7 @@ async fn broadcast_output(
let current_screen = session.parser.screen().clone(); let current_screen = session.parser.screen().clone();
let (bytes, snapshot) = if client.pending.len() >= retransmit_window { let (bytes, snapshot) = if client.pending.len() >= retransmit_window {
client.pending.clear(); client.pending.clear();
(current_screen.state_formatted(), true) (screen_snapshot(&current_screen), true)
} else { } else {
(output.bytes.clone(), false) (output.bytes.clone(), false)
}; };
@@ -758,6 +758,17 @@ async fn broadcast_session_exit(
Ok(()) Ok(())
} }
fn screen_snapshot(screen: &vt100::Screen) -> Vec<u8> {
let mut bytes = Vec::new();
if screen.alternate_screen() {
bytes.extend_from_slice(b"\x1b[?1049h");
} else {
bytes.extend_from_slice(b"\x1b[?1049l");
}
bytes.extend(screen.state_formatted());
bytes
}
async fn retransmit_pending( async fn retransmit_pending(
state: &Arc<Mutex<ServerState>>, state: &Arc<Mutex<ServerState>>,
socket: &Arc<UdpSocket>, socket: &Arc<UdpSocket>,
+57
View File
@@ -572,6 +572,63 @@ fn live_output_forwards_terminal_control_sequences() {
); );
} }
#[test]
fn resume_snapshot_preserves_alternate_screen_mode() {
let dir = tempfile::tempdir().unwrap();
let port = free_udp_port();
let config = write_server_config(&dir, port);
let mut server = start_server(&dir, &config);
let (socket, bootstrap, ok) = direct_attach(&config, port, "read-write");
let input = Input {
bytes: b"printf '\\033[?1049hALT_SNAPSHOT'\n".to_vec(),
};
send_encrypted(
&socket,
port,
PacketKind::Input,
ok.client_id,
2,
0,
&bootstrap.session_key,
&protocol::to_body(&input).unwrap(),
);
let _ = collect_frame_text(&socket, &bootstrap.session_key, 500);
let new_socket = UdpSocket::bind("127.0.0.1:0").unwrap();
new_socket
.set_read_timeout(Some(Duration::from_secs(2)))
.unwrap();
let resume = ResumeRequest {
session: "default".to_string(),
last_rendered_seq: ok.initial_seq,
cols: 80,
rows: 24,
};
send_encrypted(
&new_socket,
port,
PacketKind::ResumeRequest,
ok.client_id,
3,
0,
&bootstrap.session_key,
&protocol::to_body(&resume).unwrap(),
);
let (_header, resume_frame) =
recv_frame(&new_socket, &bootstrap.session_key).expect("resume response");
let _ = server.kill();
let _ = server.wait();
assert!(resume_frame.snapshot);
assert!(
resume_frame.bytes.starts_with(b"\x1b[?1049h"),
"snapshot did not enter alternate screen first: {:?}",
String::from_utf8_lossy(&resume_frame.bytes)
);
}
#[test] #[test]
fn resume_updates_udp_endpoint_for_roaming() { fn resume_updates_udp_endpoint_for_roaming() {
let dir = tempfile::tempdir().unwrap(); let dir = tempfile::tempdir().unwrap();