Trace reconnect failure reasons
ci / test (push) Waiting to run
ci / fuzz-smoke (push) Waiting to run
ci / windows-client (push) Waiting to run
ci / package-release (linux-x86_64, ubuntu-latest) (push) Waiting to run
ci / package-release (macos-aarch64, macos-14) (push) Waiting to run
ci / package-release (macos-x86_64, macos-13) (push) Waiting to run
ci / package-release (windows-x86_64, windows-latest) (push) Waiting to run
ci / publish-gitea-release (push) Blocked by required conditions
ci / remote-bench (push) Waiting to run

This commit is contained in:
DuProcess
2026-07-12 21:11:49 -04:00
parent f74495765f
commit 0f2cb82be6
3 changed files with 88 additions and 27 deletions
Generated
+1 -1
View File
@@ -436,7 +436,7 @@ dependencies = [
[[package]] [[package]]
name = "dosh" name = "dosh"
version = "1.0.0-rc38" version = "1.0.0-rc39"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"base64", "base64",
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "dosh" name = "dosh"
version = "1.0.0-rc38" version = "1.0.0-rc39"
edition = "2024" edition = "2024"
license = "MIT" license = "MIT"
+86 -25
View File
@@ -828,6 +828,9 @@ struct TraceReport {
sent_input_events: usize, sent_input_events: usize,
pty_write_events: usize, pty_write_events: usize,
reconnect_events: usize, reconnect_events: usize,
reconnect_none_events: usize,
reconnect_live_fail_events: usize,
reconnect_ticket_fail_events: usize,
unknown_resume_events: usize, unknown_resume_events: usize,
ticket_attach_start_events: usize, ticket_attach_start_events: usize,
ticket_attach_ok_events: usize, ticket_attach_ok_events: usize,
@@ -1345,6 +1348,15 @@ fn summarize_trace_file_with_mode(
if event.contains("reconnect") || event.contains("resume") { if event.contains("reconnect") || event.contains("resume") {
report.reconnect_events += 1; report.reconnect_events += 1;
} }
if event == "client.reconnect_none" {
report.reconnect_none_events += 1;
}
if event == "client.reconnect_live_fail" {
report.reconnect_live_fail_events += 1;
}
if event == "client.reconnect_ticket_fail" {
report.reconnect_ticket_fail_events += 1;
}
if event == "server.resume_unknown_client" { if event == "server.resume_unknown_client" {
report.unknown_resume_events += 1; report.unknown_resume_events += 1;
} }
@@ -1413,8 +1425,11 @@ fn print_trace_report(label: &str, report: &TraceReport) {
report.hex_events report.hex_events
); );
println!( println!(
" reconnect: events={} unknown_resume={} ticket_attach={}/{}/{} roam={}", " reconnect: events={} none={} live_fail={} ticket_fail={} unknown_resume={} ticket_attach={}/{}/{} roam={}",
report.reconnect_events, report.reconnect_events,
report.reconnect_none_events,
report.reconnect_live_fail_events,
report.reconnect_ticket_fail_events,
report.unknown_resume_events, report.unknown_resume_events,
report.ticket_attach_start_events, report.ticket_attach_start_events,
report.ticket_attach_ok_events, report.ticket_attach_ok_events,
@@ -1452,6 +1467,12 @@ fn trace_report_warnings(report: &TraceReport) -> Vec<String> {
report.ticket_attach_reject_events report.ticket_attach_reject_events
)); ));
} }
if report.reconnect_none_events > 0 {
warnings.push(format!(
"{} reconnect attempt(s) exhausted live resume and ticket attach",
report.reconnect_none_events
));
}
if report.server_mouseish_pty_write_events > 0 { if report.server_mouseish_pty_write_events > 0 {
warnings.push(format!( warnings.push(format!(
"{} mouse-like input event(s) reached the server PTY", "{} mouse-like input event(s) reached the server PTY",
@@ -7106,32 +7127,46 @@ async fn reconnect(
("last_rendered_seq", cred.last_rendered_seq.to_string()), ("last_rendered_seq", cred.last_rendered_seq.to_string()),
], ],
); );
if let Ok((frame, next)) = try_live_resume(socket, cred, send_seq, size.0, size.1).await { match try_live_resume(socket, cred, send_seq, size.0, size.1).await {
*cred = next; Ok((frame, next)) => {
frame_buffer.clear(); *cred = next;
predictor.reset(); frame_buffer.clear();
cred.last_rendered_seq = frame.output_seq; predictor.reset();
send_ack( cred.last_rendered_seq = frame.output_seq;
socket, send_ack(
resolve_addr(&cred.udp_host, cred.udp_port)?, socket,
cred, resolve_addr(&cred.udp_host, cred.udp_port)?,
send_seq, cred,
) send_seq,
.await?; )
dosh::trace::event( .await?;
"client.reconnect_live_ok", dosh::trace::event(
&[ "client.reconnect_live_ok",
("output_seq", frame.output_seq.to_string()), &[
("bytes", frame.bytes.len().to_string()), ("output_seq", frame.output_seq.to_string()),
], ("bytes", frame.bytes.len().to_string()),
); ],
return Ok(Some(frame)); );
return Ok(Some(frame));
}
Err(err) => {
dosh::trace::event(
"client.reconnect_live_fail",
&[("reason", format!("{err:#}"))],
);
}
} }
let Ok((frame, next)) = try_ticket_attach(socket, cred, size.0, size.1, Vec::new()).await let (frame, next) = match try_ticket_attach(socket, cred, size.0, size.1, Vec::new()).await {
else { Ok(value) => value,
dosh::trace::event("client.reconnect_none", &[]); Err(err) => {
return Ok(None); dosh::trace::event(
"client.reconnect_ticket_fail",
&[("reason", format!("{err:#}"))],
);
dosh::trace::event("client.reconnect_none", &[]);
return Ok(None);
}
}; };
*cred = next; *cred = next;
*send_seq = 2; *send_seq = 2;
@@ -10832,6 +10867,32 @@ mod tests {
); );
} }
#[test]
fn trace_report_warns_when_reconnect_exhausts_all_paths() {
let dir = tempfile::tempdir().unwrap();
let path = dir.path().join("client.log");
fs::write(
&path,
concat!(
"ts_ms=10 pid=1 event=client.start version=1.0.0\n",
"ts_ms=11 pid=1 event=client.reconnect_start session=term mode=read-write last_rendered_seq=9\n",
"ts_ms=12 pid=1 event=client.reconnect_live_fail reason='live resume timed out'\n",
"ts_ms=13 pid=1 event=client.reconnect_ticket_fail reason='ticket attach timed out'\n",
"ts_ms=14 pid=1 event=client.reconnect_none\n",
),
)
.unwrap();
let report = summarize_trace_file(&path, 10).unwrap();
let warnings = trace_report_warnings(&report);
assert_eq!(report.reconnect_none_events, 1);
assert_eq!(report.reconnect_live_fail_events, 1);
assert_eq!(report.reconnect_ticket_fail_events, 1);
assert!(warnings.iter().any(|warning| {
warning == "1 reconnect attempt(s) exhausted live resume and ticket attach"
}));
}
#[test] #[test]
fn update_installer_uses_platform_native_script() { fn update_installer_uses_platform_native_script() {
assert_eq!( assert_eq!(