



























@@ -141,6 +141,59 @@ describe("drainActiveSessionsForShutdown", () => {
141141expect((runSessionEndMock.mock.calls[0][0] as { sessionId?: string }).sessionId).toBe("sess-B");
142142});
143143144+it("awaits each session_end handler so the bounded timeout actually races real plugin work", async () => {
145+let resolveHandler: (() => void) | undefined;
146+const handlerLatch = new Promise<void>((resolve) => {
147+resolveHandler = resolve;
148+});
149+runSessionEndMock.mockImplementationOnce(async () => {
150+await handlerLatch;
151+});
152+emitGatewaySessionStartPluginHook({
153+ cfg,
154+sessionKey: "agent:main:main",
155+sessionId: "sess-A",
156+storePath: "/tmp/store.json",
157+});
158+159+let drainSettled = false;
160+const drainPromise = drainActiveSessionsForShutdown({ reason: "shutdown" }).then((value) => {
161+drainSettled = true;
162+return value;
163+});
164+165+// Yield twice so the drain can call `runSessionEnd`, then assert that
166+// it is still pending: this is the regression check for the fire-and-
167+// forget bug that the bot flagged on the original PR.
168+await Promise.resolve();
169+await Promise.resolve();
170+expect(drainSettled).toBe(false);
171+expect(runSessionEndMock).toHaveBeenCalledTimes(1);
172+173+resolveHandler?.();
174+const result = await drainPromise;
175+expect(result.timedOut).toBe(false);
176+expect(result.emittedSessionIds).toEqual(["sess-A"]);
177+});
178+179+it("returns timedOut=true and surfaces the elapsed budget when a plugin handler hangs", async () => {
180+runSessionEndMock.mockImplementationOnce(() => new Promise<void>(() => undefined));
181+emitGatewaySessionStartPluginHook({
182+ cfg,
183+sessionKey: "agent:main:main",
184+sessionId: "sess-A",
185+storePath: "/tmp/store.json",
186+});
187+188+const result = await drainActiveSessionsForShutdown({
189+reason: "shutdown",
190+totalTimeoutMs: 120,
191+});
192+193+expect(result.timedOut).toBe(true);
194+expect(runSessionEndMock).toHaveBeenCalledTimes(1);
195+});
196+144197it("still records the session as forgotten when no `session_end` plugins are registered", async () => {
145198hasHooksMock.mockImplementation(() => false);
146199emitGatewaySessionStartPluginHook({
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。