FN-6626: close cached CLI extension task stores
Close cached TaskStore handles so CLI extension task-tool tests shut down cleanly.\n\n- Add deterministic cached-store shutdown for the CLI extension and invoke it from extension teardown.\n- Expose the shutdown helper for tests and call it after canonical-project-root task-tool cases.\n- Add a patch changeset for the published @runfusion/fusion package.\n\nFiles changed:\n .changeset/fn-6626-close-cached-stores.md | 5 +++++\n .../cli/src/__tests__/extension-task-tools.test.ts | 8 ++++++++\n packages/cli/src/extension.ts | 19 ++++++++++++++++++-\n 3 files changed, 31 insertions(+), 1 deletion(-) Fusion-Task-Id: FN-6626 Fusion-Task-Lineage: 65791502-8992-4037-8ca0-fe21c8283506
This commit is contained in:
5
.changeset/fn-6626-close-cached-stores.md
Normal file
5
.changeset/fn-6626-close-cached-stores.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@runfusion/fusion": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Close cached CLI extension TaskStore instances on session shutdown so task-tool runs do not leave SQLite handles behind.
|
||||||
@@ -6,6 +6,9 @@ Keep this worktree-root regression slice fast by relying on module resets and bo
|
|||||||
|
|
||||||
FNXC:CliTests 2026-06-15-07:44:
|
FNXC:CliTests 2026-06-15-07:44:
|
||||||
FN-6486 rescues this load-only timeout by closing each real TaskStore before removing its temp root and by using non-hoisted mock cleanup. The suite keeps the worktree-root regression coverage without widening timeouts, adding retries, or changing package worker settings.
|
FN-6486 rescues this load-only timeout by closing each real TaskStore before removing its temp root and by using non-hoisted mock cleanup. The suite keeps the worktree-root regression coverage without widening timeouts, adding retries, or changing package worker settings.
|
||||||
|
|
||||||
|
FNXC:CliTests 2026-06-17-23:58:
|
||||||
|
FN-6626 requires these canonical-project-root tool tests to close the extension module's cached TaskStore instances after every case, because fixture-store cleanup alone does not close the second store opened by fn_task_show/fn_task_list.
|
||||||
*/
|
*/
|
||||||
import { mkdtemp, mkdir, rm, writeFile } from "node:fs/promises";
|
import { mkdtemp, mkdir, rm, writeFile } from "node:fs/promises";
|
||||||
import { tmpdir } from "node:os";
|
import { tmpdir } from "node:os";
|
||||||
@@ -17,8 +20,11 @@ function makeCtx(cwd: string) {
|
|||||||
return { cwd } as any;
|
return { cwd } as any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let closeLoadedExtensionStores: (() => void) | undefined;
|
||||||
|
|
||||||
async function loadExtension() {
|
async function loadExtension() {
|
||||||
const mod = await import("../extension.js");
|
const mod = await import("../extension.js");
|
||||||
|
closeLoadedExtensionStores = mod.closeCachedStores;
|
||||||
return mod.default;
|
return mod.default;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,6 +38,8 @@ describe("extension task tools resolve repo root from worktrees", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
closeLoadedExtensionStores?.();
|
||||||
|
closeLoadedExtensionStores = undefined;
|
||||||
vi.restoreAllMocks();
|
vi.restoreAllMocks();
|
||||||
vi.doUnmock("@fusion/core");
|
vi.doUnmock("@fusion/core");
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -152,6 +152,23 @@ async function getStore(cwd: string): Promise<TaskStore> {
|
|||||||
return store;
|
return store;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @internal Exposed so tests and the extension shutdown hook can close cached stores deterministically; not a public CLI API contract. */
|
||||||
|
export function closeCachedStores(): void {
|
||||||
|
/*
|
||||||
|
FNXC:CliTests 2026-06-17-23:58:
|
||||||
|
FN-6626 found the CLI extension cache cleared real TaskStore instances without closing them, leaving SQLite/WAL handles to survive module resets and making canonical-project-root task-tool tests timeout under suite load.
|
||||||
|
Close every cached store deterministically on extension shutdown and in tests; do not appease the load-sensitive seam with timeouts, retries, or worker changes.
|
||||||
|
*/
|
||||||
|
for (const store of storeCache.values()) {
|
||||||
|
try {
|
||||||
|
store.close();
|
||||||
|
} catch (error) {
|
||||||
|
console.warn("[fusion-extension] cached TaskStore close skipped", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
storeCache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
function getFusionDir(cwd: string): string {
|
function getFusionDir(cwd: string): string {
|
||||||
return join(resolveProjectRoot(cwd), ".fusion");
|
return join(resolveProjectRoot(cwd), ".fusion");
|
||||||
}
|
}
|
||||||
@@ -4572,6 +4589,6 @@ export default function kbExtension(pi: ExtensionAPI) {
|
|||||||
dashboardProcess = null;
|
dashboardProcess = null;
|
||||||
dashboardPort = null;
|
dashboardPort = null;
|
||||||
}
|
}
|
||||||
storeCache.clear();
|
closeCachedStores();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user