Skip to content

Changing Azure DevOps credentials disposes the VssConnection that in-flight requests are still using #298

Description

@matt-edmondson

What's wrong

CredentialedSessionCache.Get() (BuildMonitor/Providers/CredentialedSessionCache.cs:75, called from AzureDevOps.cs:89) handles changed credentials by calling Invalidate(), which disposes the previous session (VssConnection) immediately.

Callers that already got that session keep it across the rate-limit delay and the HTTP call, and up to 5 requests can be in flight at once. The class remarks say a rebuild "does not disturb a request already in flight", but disposing the session does exactly that.

Why it matters

  • In-flight calls fail with ObjectDisposedException.
  • MakeAzureDevOpsRequestAsync only catches Vss* exceptions and HttpRequestException, so the ObjectDisposedException escapes and faults the update loop.
  • The Set Credentials flow changes AccountId and then Token in two separate popups, so it triggers two rebuilds while polling continues. This is the ordinary path for re-entering a PAT, not a rare race.
  • The existing test ASessionHandedToACallerSurvivesARebuildBehindIt only reads a string off the fake session, so it never checks disposal.

Reproduction (ran)

  1. Get("org", "pat1"), keep the result.
  2. Get("org", "pat2").
  3. Result: the first session reports Disposed == true while its holder may still be using it.

Suggested fix / acceptance criteria

  • Either lease sessions with a reference count and dispose a replaced session only when its last holder releases it, or defer disposal of replaced sessions.
  • At minimum, have MakeAzureDevOpsRequestAsync catch ObjectDisposedException and retry once with a fresh session.
  • Extend the existing test to assert that the session handed out earlier is not disposed while it is held.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

bugSomething isn't workingreadyFully specified; implement as written

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions