Skip to content

Commit 4d605a7

Browse files
committed
Retry idempotent session detach
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 69723dd2-e732-43c6-9f9a-a16c2de3a628
1 parent a5be150 commit 4d605a7

2 files changed

Lines changed: 24 additions & 4 deletions

File tree

nodejs/src/session.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1969,9 +1969,12 @@ export class CopilotSession {
19691969
if (this.disconnected) {
19701970
return;
19711971
}
1972-
const response = (await this.connection.sendRequest("session.detach", {
1973-
sessionId: this.sessionId,
1974-
})) as { success: boolean; error?: string };
1972+
let response: { success: boolean; error?: string } = { success: false };
1973+
for (let attempt = 0; attempt < 2 && !response.success; attempt++) {
1974+
response = (await this.connection.sendRequest("session.detach", {
1975+
sessionId: this.sessionId,
1976+
})) as { success: boolean; error?: string };
1977+
}
19751978
if (!response.success) {
19761979
throw new Error(
19771980
`Failed to disconnect session ${this.sessionId}: ${response.error || "Unknown error"}`

nodejs/test/client.test.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2208,7 +2208,24 @@ describe("CopilotClient", () => {
22082208
await expect(session.disconnect()).resolves.toBeUndefined();
22092209
expect(
22102210
sendRequest.mock.calls.filter(([method]) => method === "session.detach")
2211-
).toHaveLength(2);
2211+
).toHaveLength(3);
2212+
});
2213+
2214+
it("retries an unsuccessful detach response before disconnecting", async () => {
2215+
const sendRequest = vi
2216+
.fn()
2217+
.mockResolvedValueOnce({ success: false, error: "cleanup raced" })
2218+
.mockResolvedValueOnce({ success: true });
2219+
const session = new CopilotSession(
2220+
"test-session",
2221+
{ sendRequest } as any,
2222+
undefined,
2223+
undefined
2224+
);
2225+
2226+
await expect(session.disconnect()).resolves.toBeUndefined();
2227+
await expect(session.getEvents()).rejects.toThrow("has been disconnected");
2228+
expect(sendRequest).toHaveBeenCalledTimes(2);
22122229
});
22132230

22142231
it("detaches a session when asynchronously disposed", async () => {

0 commit comments

Comments
 (0)