feat(vscode-ide-companion/auth): deduplicate concurrent authentication calls

Prevent multiple simultaneous authentication flows by:
- Adding static authInFlight promise tracking in AcpConnection
- Implementing runExclusiveAuth method in AuthStateManager
- Adding sessionCreateInFlight tracking in QwenAgentManager
- Ensuring only one auth flow runs at a time across different components

This prevents race conditions and duplicate login prompts when multiple components request authentication simultaneously.
This commit is contained in:
yiliang114
2025-12-11 22:56:58 +08:00
parent 58d3a9c253
commit b34894c8ea
12 changed files with 589 additions and 464 deletions

View File

@@ -31,6 +31,8 @@ export class AcpConnection {
private child: ChildProcess | null = null;
private pendingRequests = new Map<number, PendingRequest<unknown>>();
private nextRequestId = { value: 0 };
// Deduplicate concurrent authenticate calls (across retry paths)
private static authInFlight: Promise<AcpResponse> | null = null;
// Remember the working dir provided at connect() so later ACP calls
// that require cwd (e.g. session/list) can include it.
private workingDir: string = process.cwd();
@@ -271,12 +273,23 @@ export class AcpConnection {
* @returns Authentication response
*/
async authenticate(methodId?: string): Promise<AcpResponse> {
return this.sessionManager.authenticate(
methodId,
this.child,
this.pendingRequests,
this.nextRequestId,
);
if (AcpConnection.authInFlight) {
return AcpConnection.authInFlight;
}
const p = this.sessionManager
.authenticate(
methodId,
this.child,
this.pendingRequests,
this.nextRequestId,
)
.finally(() => {
AcpConnection.authInFlight = null;
});
AcpConnection.authInFlight = p;
return p;
}
/**