Skip to content

Commit 42a84e2

Browse files
jmoseleyCopilot
andauthored
Improve Rust permission confirmation reliability (#2470)
Surface confirmation RPC failures with structured context and cancel unresolved acknowledgement waits during session teardown. Add deterministic coverage for error, write-failure, missing-response, teardown, and success paths. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent 040530f commit 42a84e2

2 files changed

Lines changed: 413 additions & 15 deletions

File tree

rust/src/session.rs

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1567,7 +1567,7 @@ fn spawn_event_loop(
15671567
_ = shutdown.cancelled() => break,
15681568
Some(notification) = notifications.recv() => {
15691569
handle_notification(
1570-
&session_id, &client, &handlers, &command_handlers, notification, &idle_waiter, &capabilities, &open_canvases, &event_tx,
1570+
&session_id, &client, &handlers, &command_handlers, notification, &idle_waiter, &capabilities, &open_canvases, &event_tx, &shutdown,
15711571
).await;
15721572
}
15731573
Some(request) = requests.recv() => {
@@ -1719,6 +1719,7 @@ async fn handle_notification(
17191719
capabilities: &Arc<parking_lot::RwLock<SessionCapabilities>>,
17201720
open_canvases: &Arc<parking_lot::RwLock<Vec<OpenCanvasInstance>>>,
17211721
event_tx: &tokio::sync::broadcast::Sender<SessionEvent>,
1722+
shutdown: &CancellationToken,
17221723
) {
17231724
let dispatch_start = Instant::now();
17241725
let event = notification.event.clone();
@@ -1856,6 +1857,7 @@ async fn handle_notification(
18561857
};
18571858
let client = client.clone();
18581859
let sid = session_id.clone();
1860+
let shutdown = shutdown.clone();
18591861
let data = permission_request_data(
18601862
&notification.event.data,
18611863
handlers.managed_settings_enabled,
@@ -1885,18 +1887,39 @@ async fn handle_notification(
18851887
return;
18861888
};
18871889
let rpc_start = Instant::now();
1888-
let _ = client
1889-
.call(
1890-
rpc_methods::SESSION_PERMISSIONS_HANDLEPENDINGPERMISSIONREQUEST,
1891-
Some(params),
1892-
)
1893-
.await;
1894-
tracing::debug!(
1895-
elapsed_ms = rpc_start.elapsed().as_millis(),
1896-
session_id = %sid,
1897-
request_id = %request_id,
1898-
"Session::handle_notification response sent successfully"
1899-
);
1890+
let method =
1891+
rpc_methods::SESSION_PERMISSIONS_HANDLEPENDINGPERMISSIONREQUEST;
1892+
tokio::select! {
1893+
biased;
1894+
response = client.call(method, Some(params)) => {
1895+
match response {
1896+
Ok(_) => tracing::debug!(
1897+
elapsed_ms = rpc_start.elapsed().as_millis(),
1898+
session_id = %sid,
1899+
request_id = %request_id,
1900+
method,
1901+
"Session::handle_notification response sent successfully"
1902+
),
1903+
Err(error) => warn!(
1904+
error = %error,
1905+
session_id = %sid,
1906+
request_id = %request_id,
1907+
method,
1908+
"failed to deliver permission decision back to the runtime"
1909+
),
1910+
}
1911+
}
1912+
_ = shutdown.cancelled() => {
1913+
warn!(
1914+
elapsed_ms = rpc_start.elapsed().as_millis(),
1915+
session_id = %sid,
1916+
request_id = %request_id,
1917+
method,
1918+
delivery_outcome = "unknown",
1919+
"permission confirmation acknowledgement wait cancelled during session shutdown"
1920+
);
1921+
}
1922+
}
19001923
}
19011924
.instrument(span),
19021925
);

0 commit comments

Comments
 (0)