Skip to content

Fix authentication provider cleanup when an extension host stops - #345127

Merged
Connor Peet (connor4312) merged 10 commits into
microsoft:mainfrom
wozhenbang2004:fix-auth-provider-lifecycle-343316
Nov 9, 2026
Merged

Connor Peet (connor4312) merged 10 commits into
microsoft:mainfrom
wozhenbang2004:fix-auth-provider-lifecycle-343316

Conversation

@wozhenbang2004

@wozhenbang2004 Kayokoi (wozhenbang2004) commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

Related to #343316.

Authentication providers can remain in AuthenticationService after their owning MainThreadAuthentication customer is disposed, leaving discovery to reuse a provider backed by the old RPC proxy. The customer already is disposed when its extension host stops; the missing cleanup is the service's independent provider registration.

Provider deregistration now belongs to the registration's disposer, so both explicit unregistration and customer disposal use the same cleanup. External unregistration also releases the local registration, and cleanup suppresses only the owning host's unregister echo.

The focused regression tests check that disposal deregisters the provider without additional client-registration writes. The RPCProtocol test models the manager's teardown order, verifies cancellation through the old proxy, and checks that a fresh host can register with the same authentication service. Three additional tests cover explicit unregistration, external unregistration followed by registration on another host and teardown of the old host, and notifications to surviving hosts.

Earlier validation for ecaef8a5b708092acb0dff35fc8ea3323aa81d5f passed in this isolated fork run: changed-file hygiene and ESLint, full client typecheck/transpilation, and the official Electron suites (12 MainThreadAuthentication tests and 24 AuthenticationService tests, plus one clean-state harness check per invocation; JUnit totals 13 and 25, no failures/errors/skips).

The same RPC regression was then run with only the production mainThreadAuthentication.ts replaced by its unpatched version from cd2259bdf72ec7421e70ae80999ceb46f8bd86fe. It failed at provider discovery: actual dynamic-provider, expected undefined, after the real cancellation assertion had passed. Logs and JUnit artifact. The validation workflow stays on a separate fork branch, not in this PR.

This establishes the component-level lifecycle defect, not the original live Datadog OAuth/Add Folder to Workspace scenario. I have not reproduced that end-to-end flow or confirmed this resolves all of #343316.

The official Electron suites and client typecheck have not been rerun for revision e5886065e6ebcff0e1a712c49407c23233b71b61.

Unregister authentication providers when their main-thread customer is disposed,
without removing replacements registered by another extension host. Keep OAuth
storage intact.

Related to microsoft#343316.
Cover host replacement, cross-host isolation, late unregister calls, and
registration/session event behavior.

Related to microsoft#343316.
Copilot AI balanced review requested due to automatic review settings October 30, 2026 05:37
@vs-code-engineering

Copy link
Copy Markdown
Contributor

📬 CODENOTIFY

The following users are being notified based on files changed in this PR:

TylerLeonhardt

Matched files:

  • src/vs/workbench/api/browser/mainThreadAuthentication.ts

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.

🟡 Changes recommended

A stale unregister notification can delete a newly registered authentication provider, leaving session requests to fail; the ordering also needs a regression test.

1 open issue
What changed in this PR

This PR addresses stale authentication providers after extension-host replacement, related to #343316, by tying provider cleanup to the owning host’s lifetime.

Changes:

  • Unregisters host-owned providers on disposal while preserving same-ID replacements.
  • Suppresses unregister notifications to the stopping host without deleting persisted OAuth data.
  • Adds lifecycle tests for replacement, cross-host isolation, late unregister calls, and event behavior.
File Description
src/​vs/​workbench/​api/​test/​browser/​mainThreadAuthentication.test.ts Adds provider lifecycle and host-replacement regression tests.
src/​vs/​workbench/​api/​browser/​mainThreadAuthentication.ts Adds ownership-aware provider cleanup during disposal and explicit unregister.

Review effort: Balanced

Discard superseded registrations and notify only the host that owns the removed provider.

Related to microsoft#343316.
Cover both registration orderings with the real extension-host queue and preserve normal external unregistration.

Client typecheck and the official Electron suites pass (11 + 24 tests):
https://github.com/wozhenbang2004/vscode/actions/runs/41013263036

@connor4312 Connor Peet (connor4312) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The entire MainThreadAuthentication will be disposed when the corresponding extension host stops. I think you're barking up the wrong tree here, unless you're able to actually repro something...

Updated createHost and registerDynamicProvider functions to include RPCProtocol and improve dynamic provider registration handling. Added tests for rediscovering dynamic providers after RPC and customer disposal.
Register a typed server actor rather than a DTO-shaped client proxy. The disposal test still uses production RPCProtocol cancellation.
@wozhenbang2004

Copy link
Copy Markdown
Contributor Author

Connor Peet (@connor4312) You're right that the whole MainThreadAuthentication customer is disposed. My earlier tests didn't establish what happens through a disposed RPC connection.

The remaining registration is in AuthenticationService's separate provider map. On the unpatched baseline, the customer's _registrations owns only the session emitter, so disposing the customer doesn't unregister that provider.

I've added rediscovers dynamic providers after RPC and customer disposal using paired production RPCProtocol instances. It registers and gets sessions across RPC, disposes RPC then the entire customer (modeling the manager's teardown order), verifies the retained provider rejects with an actual cancellation, and checks discovery before registering a fresh RPC host against the same service.

At ecaef8a5b708092acb0dff35fc8ea3323aa81d5f, the isolated fork run passes hygiene, ESLint, full client typecheck/transpilation and the official Electron suites: 12 authentication-customer tests + 24 service tests (13/25 including each runner's clean-state check). With the same test and only mainThreadAuthentication.ts substituted from unpatched cd2259bdf72ec7421e70ae80999ceb46f8bd86fe, the cancellation assertion passes but discovery fails: actual dynamic-provider, expected undefined. Logs and JUnit.

This is a component-level reproduction with real RPC disposal, not a real extension-host process restart or the original Datadog/Add Folder flow. I haven't reproduced that end-to-end scenario, so I can't yet claim this proves the cause of #343316. The PR description now makes that boundary explicit.

@connor4312

Copy link
Copy Markdown
Member

Your PR seems to add additional guards against "Another extension host may have replaced the provider registered by this host" which I think are not related to the issue; just the lack of deregistration

Removed unused imports and simplified function signatures in mainThreadAuthentication tests.
Cover explicit unregistration, external removal followed by registration on another host, and notifications to surviving hosts.
Unregister providers from their registration disposer, preserve owner notification suppression, and release registrations after external unregistration. Remove the separate disposal override and provider identity check.
@connor4312
Connor Peet (connor4312) merged commit 50e1350 into microsoft:main Nov 9, 2026
52 checks passed
@vs-code-engineering vs-code-engineering Bot added this to the 1.147.0 milestone Nov 9, 2026
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.

5 participants