Skip to content

Commit d1b2cc5

Browse files
Copilotglharper
andauthored
Fix abort signal propagation in memory store update poller (#36707)
The `buildRunningOperation` function wasn't receiving the user-provided `options.abortSignal`, preventing proper cancellation of ongoing poll requests. **Changes:** - Pass `options` parameter to `buildRunningOperation` to capture user-provided abort signal - Update `sendPollRequest` to listen to both `options.abortSignal` and `pollOptions?.abortSignal` - Add event listeners for both signals with proper cleanup in finally block This aligns with the reference implementation in `pollingHelpers.ts` lines 53-94. ```typescript // Before: only pollOptions abort signal was handled sendPollRequest: async (path: string, pollOptions?: { abortSignal?: AbortSignalLike }) => { if (pollOptions?.abortSignal?.aborted) { pollAbortController.abort(); } // ... } // After: both user-provided and poll-specific signals are handled sendPollRequest: async (path: string, pollOptions?: { abortSignal?: AbortSignalLike }) => { if (options?.abortSignal?.aborted) { pollAbortController.abort(); } else if (pollOptions?.abortSignal?.aborted) { pollAbortController.abort(); } else if (!abortSignal.aborted) { options?.abortSignal?.addEventListener("abort", abortListener, { once: true }); pollOptions?.abortSignal?.addEventListener("abort", abortListener, { once: true }); } // ... } ``` <!-- START COPILOT CODING AGENT TIPS --> --- 💬 We'd love your input! Share your thoughts on Copilot coding agent in our [2 minute survey](https://gh.io/copilot-coding-agent-survey). --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: glharper <[email protected]>
1 parent cae1fc3 commit d1b2cc5

File tree

1 file changed

+10
-1
lines changed

1 file changed

+10
-1
lines changed

sdk/ai/ai-projects/src/api/memoryStores/memoryStoreUpdatePoller.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ function buildRunningOperation(
135135
client: Client,
136136
expectedStatuses: string[],
137137
getInitialResponse?: () => PromiseLike<PathUncheckedResponse>,
138+
options?: CreateMemoryStoreUpdatePollerOptions,
138139
): RunningOperation<PathUncheckedResponse> {
139140
const pollAbortController = new AbortController();
140141
return {
@@ -146,13 +147,19 @@ function buildRunningOperation(
146147
return toOperationResponse(initialResponse, expectedStatuses);
147148
},
148149
sendPollRequest: async (path: string, pollOptions?: { abortSignal?: AbortSignalLike }) => {
150+
// The poll request will both listen to the user provided abort signal and the poller's own abort signal
149151
function abortListener(): void {
150152
pollAbortController.abort();
151153
}
152154
const abortSignal = pollAbortController.signal;
153-
if (pollOptions?.abortSignal?.aborted) {
155+
if (options?.abortSignal?.aborted) {
156+
pollAbortController.abort();
157+
} else if (pollOptions?.abortSignal?.aborted) {
154158
pollAbortController.abort();
155159
} else if (!abortSignal.aborted) {
160+
options?.abortSignal?.addEventListener("abort", abortListener, {
161+
once: true,
162+
});
156163
pollOptions?.abortSignal?.addEventListener("abort", abortListener, {
157164
once: true,
158165
});
@@ -162,6 +169,7 @@ function buildRunningOperation(
162169
try {
163170
response = (await client.pathUnchecked(path).get({ abortSignal })) as PathUncheckedResponse;
164171
} finally {
172+
options?.abortSignal?.removeEventListener("abort", abortListener);
165173
pollOptions?.abortSignal?.removeEventListener("abort", abortListener);
166174
}
167175

@@ -191,6 +199,7 @@ export function createMemoryStoreUpdatePoller(
191199
return initialResponse;
192200
}
193201
: undefined,
202+
options,
194203
),
195204
{
196205
intervalInMs: options?.updateIntervalInMs,

0 commit comments

Comments
 (0)