Skip to content

Rust: add race-safe canvas availability waiter - #2290

Open
ellismg wants to merge 1 commit into
mainfrom
ellismg-canvas-lifecycle-api
Open

Rust: add race-safe canvas availability waiter#2290
ellismg wants to merge 1 commit into
mainfrom
ellismg-canvas-lifecycle-api

Conversation

@ellismg

@ellismg ellismg commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add Session::wait_for_canvas(WaitForCanvasOptions) for waiting on a known canvas declaration without sending a model turn
  • subscribe before the initial session.canvas.list snapshot, then re-list on registry changes or subscription lag
  • support provider-specific matching, total timeouts, and deterministic session-shutdown errors
  • cover existing declarations, registration races, lag recovery, timeout/no-turn behavior, and shutdown during both event waiting and an in-flight list request

Motivation

github/github-app#11029 currently has to coordinate session.canvas.list and session.canvas.registry_changed itself while asynchronously loaded extensions register their canvases. This helper provides the smallest SDK-level primitive that removes the list/subscription race when the caller already knows the target canvas.

The API deliberately guarantees only target availability. It does not claim that extension initialization or the complete canvas registry has settled. A handshake-backed bounded initialization snapshot remains a separate copilot-agent-runtime protocol follow-up for github/github-app#7544 and github/github-app#10224.

Compatibility

This is an additive Rust API implemented entirely over existing protocol-v3 methods and events. It does not change session.create, add wire fields, block session creation on extension startup, or require a model turn. Older runtimes therefore need no protocol changes.

CHANGELOG.md is release-generated and has no unreleased section, so this PR relies on public rustdoc rather than editing it manually.

Validation

  • cargo +nightly-2026-04-14 fmt --all -- --config-path .rustfmt.nightly.toml --check
  • cargo clippy --all-targets --features test-support -- --no-deps -D warnings -D clippy::unwrap_used -D clippy::disallowed_macros -D clippy::await_holding_invalid_type
  • cargo test --features test-support

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@ellismg
ellismg requested a review from a team as a code owner August 7, 2026 04:59
Copilot AI balanced review requested due to automatic review settings August 7, 2026 04:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a Rust helper for race-safe waiting on canvas declarations without starting a model turn.

Changes:

  • Adds Session::wait_for_canvas with provider matching and timeout handling.
  • Adds dedicated timeout and session-closed errors.
  • Adds coverage for registration races, lag, shutdown, and timeout behavior.
Show a summary per file
File Description
rust/src/session.rs Implements the canvas availability waiter.
rust/src/types.rs Defines waiter configuration options.
rust/src/errors.rs Adds canvas-wait error variants and messages.
rust/tests/session_test.rs Tests matching, races, lag, timeout, and shutdown.

Review details

  • Files reviewed: 4/4 changed files
  • Comments generated: 2
  • Review effort level: Balanced

Comment thread rust/src/session.rs
Comment on lines +368 to +370
Err(error) => match error.kind() {
RecvErrorKind::Lagged(_) => break,
RecvErrorKind::Closed => {
Comment on lines +3496 to +3502
let initial_list = server.read_request().await;
for sequence in 0..600 {
server
.send_event("test.event", serde_json::json!({ "sequence": sequence }))
.await;
}
tokio::time::sleep(Duration::from_millis(50)).await;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants