fix(gateway): abort active runs during sessions.reset (#16576)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 43da87f2df
Co-authored-by: Grynn <212880+Grynn@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
This commit is contained in:
Vishal Doshi
2026-02-15 04:12:33 +05:30
committed by GitHub
parent d8da642611
commit 3efb752124
3 changed files with 189 additions and 21 deletions

View File

@@ -88,6 +88,33 @@ function archiveSessionTranscriptsForSession(params: {
});
}
async function ensureSessionRuntimeCleanup(params: {
cfg: ReturnType<typeof loadConfig>;
key: string;
target: ReturnType<typeof resolveGatewaySessionStoreTarget>;
sessionId?: string;
}) {
const queueKeys = new Set<string>(params.target.storeKeys);
queueKeys.add(params.target.canonicalKey);
if (params.sessionId) {
queueKeys.add(params.sessionId);
}
clearSessionQueues([...queueKeys]);
stopSubagentsForRequester({ cfg: params.cfg, requesterSessionKey: params.target.canonicalKey });
if (!params.sessionId) {
return undefined;
}
abortEmbeddedPiRun(params.sessionId);
const ended = await waitForEmbeddedPiRunEnd(params.sessionId, 15_000);
if (ended) {
return undefined;
}
return errorShape(
ErrorCodes.UNAVAILABLE,
`Session ${params.key} is still active; try again in a moment.`,
);
}
export const sessionsHandlers: GatewayRequestHandlers = {
"sessions.list": ({ params, respond }) => {
if (!validateSessionsListParams(params)) {
@@ -278,6 +305,13 @@ export const sessionsHandlers: GatewayRequestHandlers = {
const cfg = loadConfig();
const target = resolveGatewaySessionStoreTarget({ cfg, key });
const { entry } = loadSessionEntry(key);
const sessionId = entry?.sessionId;
const cleanupError = await ensureSessionRuntimeCleanup({ cfg, key, target, sessionId });
if (cleanupError) {
respond(false, undefined, cleanupError);
return;
}
const storePath = target.storePath;
let oldSessionId: string | undefined;
let oldSessionFile: string | undefined;
@@ -360,27 +394,10 @@ export const sessionsHandlers: GatewayRequestHandlers = {
const { entry } = loadSessionEntry(key);
const sessionId = entry?.sessionId;
const existed = Boolean(entry);
const queueKeys = new Set<string>(target.storeKeys);
queueKeys.add(target.canonicalKey);
if (sessionId) {
queueKeys.add(sessionId);
}
clearSessionQueues([...queueKeys]);
stopSubagentsForRequester({ cfg, requesterSessionKey: target.canonicalKey });
if (sessionId) {
abortEmbeddedPiRun(sessionId);
const ended = await waitForEmbeddedPiRunEnd(sessionId, 15_000);
if (!ended) {
respond(
false,
undefined,
errorShape(
ErrorCodes.UNAVAILABLE,
`Session ${key} is still active; try again in a moment.`,
),
);
return;
}
const cleanupError = await ensureSessionRuntimeCleanup({ cfg, key, target, sessionId });
if (cleanupError) {
respond(false, undefined, cleanupError);
return;
}
await updateSessionStore(storePath, (store) => {
const { primaryKey } = migrateAndPruneSessionStoreKey({ cfg, key, store });