Skip to content

Clean up more argument validation#1328

Merged
stephentoub merged 9 commits into
mainfrom
stephentoub/fix-session-leak
May 19, 2026
Merged

Clean up more argument validation#1328
stephentoub merged 9 commits into
mainfrom
stephentoub/fix-session-leak

Conversation

@stephentoub
Copy link
Copy Markdown
Collaborator

@stephentoub stephentoub commented May 19, 2026

Clean up argument validation and disposal handling in CopilotClient/Session and the various generated Rpc wrappers. Also lazily allocate lots of objects.

Keep CopilotSession instances rooted by the owning client until explicit cleanup, route generated session RPC APIs through CopilotSession, and add generated argument validation plus lifetime regression tests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 19, 2026 01:52
@stephentoub stephentoub requested a review from a team as a code owner May 19, 2026 01:52
@stephentoub stephentoub changed the title Fix .NET session lifetime rooting Clean up more argument validation May 19, 2026
Comment thread dotnet/src/Client.cs Fixed
@github-actions

This comment has been minimized.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the .NET SDK session lifetime model so CopilotClient strongly roots active sessions for event routing/cleanup, and adjusts generated session RPC APIs to operate through CopilotSession.

Changes:

  • Adds session registration/removal lifecycle changes in CopilotClient/CopilotSession.
  • Regenerates .NET RPC APIs with lazy API groups, session-backed leaf APIs, disposal checks, and required-argument null checks.
  • Adds focused .NET unit coverage for session rooting, cleanup, and post-disposal RPC behavior.
Show a summary per file
File Description
scripts/codegen/csharp.ts Updates C# RPC generation for lazy API groups, session-backed RPC APIs, and null validation.
dotnet/src/Generated/Rpc.cs Regenerated RPC surface reflecting the codegen changes.
dotnet/src/Client.cs Adds strong session registry semantics and identity-aware session registration/removal helpers.
dotnet/src/Session.cs Stores parent client/session RPC state, adds disposal checks, and removes sessions from the client on cleanup.
dotnet/src/Polyfills/DownlevelExtensions.cs Adds downlevel helpers for disposal and exception dispatch APIs.
dotnet/test/Unit/ClientSessionLifetimeTests.cs Adds regression tests for rooted sessions, disposal cleanup, stop cleanup, and disposed generated RPC calls.

Copilot's findings

  • Files reviewed: 5/6 changed files
  • Comments generated: 4

Comment thread dotnet/src/Client.cs Outdated
Comment thread dotnet/src/Client.cs
Comment thread dotnet/src/Session.cs Outdated
Comment thread dotnet/src/Client.cs
Allow a resumed session to replace the client's current session entry so same-client resumes continue to work while stale session disposal cannot remove the replacement.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

This comment has been minimized.

Restore StopAsync cleanup error propagation, clear any sessions missed by concurrent registration during stop, and remove an unused Session using.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

This comment has been minimized.

Delay removing sessions from the client until session.destroy completes so destroy-time callbacks such as session_fs can still route to the session.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

This comment has been minimized.

Copilot AI added 2 commits May 18, 2026 23:00
Give mode handler callbacks the same 30 second allowance as their corresponding events to avoid Windows timing failures.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Reject same-client resumes for session ids already tracked by the client, and start session event processing only after successful registration so failed duplicate registration does not leave an untracked event loop.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

This comment has been minimized.

Copilot AI added 2 commits May 18, 2026 23:18
Update resume-focused E2E tests to use an active session from a second TCP client, while keeping same-client active resume covered as an intentional rejection. Clean up permission resume tests so the resumed handler is the only active handler.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

This comment has been minimized.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor

Cross-SDK Consistency Review ✅

This PR contains exclusively .NET SDK internal improvements with no cross-SDK consistency issues.

What changed:

  • dotnet/src/Client.cs / Session.cs / Generated/Rpc.cs: Internal refactoring — lazy allocation using C# 13's field keyword + Interlocked.CompareExchange, argument validation (ThrowIfDisposed), improved disposal handling, ExceptionDispatchInfo.Throw for better stack traces
  • scripts/codegen/csharp.ts: Updated code generator to emit lazy-initialized properties (C#-specific pattern)
  • test/harness/replayingCapiProxy.ts: Added normalizeReadAgentTimings normalizer for read_agent tool results — this is shared infrastructure that benefits all SDK E2E tests equally

Why no cross-SDK action needed:

  • No new public API methods or types were added
  • The lazy initialization pattern (field ??= ...) is a C#-specific optimization with no equivalent need in other languages
  • The ThrowIfDisposed guards are a defensive improvement; the other SDKs (Node.js, Python, Go) use different lifecycle patterns and don't have a corresponding gap to fill
  • The IOException vs Exception change in error types from StopAsync/ForceStopAsync is an internal .NET exception hierarchy detail

Generated by SDK Consistency Review Agent for issue #1328 · ● 477.5K ·

Copy link
Copy Markdown
Contributor

@SteveSandersonMS SteveSandersonMS left a comment

Choose a reason for hiding this comment

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

Looks great. I'm guessing there are equivalents to this for other languages?

@stephentoub stephentoub added this pull request to the merge queue May 19, 2026
Merged via the queue into main with commit 15439b3 May 19, 2026
44 checks passed
@stephentoub stephentoub deleted the stephentoub/fix-session-leak branch May 19, 2026 08:02
@stephentoub
Copy link
Copy Markdown
Collaborator Author

Looks great. I'm guessing there are equivalents to this for other languages?

Yup

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.

4 participants