mirror of
https://github.com/cline/cline.git
synced 2026-10-24 02:02:27 +08:00
fix(hub): close owned session store during shutdown
This commit is contained in:
@@ -1252,3 +1252,7 @@ reports active plugin requests in both `session.list` activity and `hub.status`;
|
||||
replacement and recovery checks count these requests even when no chat is attached.
|
||||
Admission is drained before activity is checked, preventing new plugin work from
|
||||
starting between the idle check and retirement.
|
||||
|
||||
The Hub owns the SQLite session store it creates for its default local runtime
|
||||
and closes that store after runtime shutdown. An injected session host retains
|
||||
ownership of its persistence resources.
|
||||
|
||||
@@ -281,6 +281,7 @@ export class HubServerTransport implements NativeHubTransport {
|
||||
private readonly settings: CoreSettingsService;
|
||||
private readonly pluginCommands: HubPluginCommandService;
|
||||
private readonly sessionSearch: SessionHistorySearchService;
|
||||
private readonly sessionStore?: SqliteSessionStore;
|
||||
private readonly cronService?: CronService;
|
||||
private readonly sessionHost: RuntimeHost &
|
||||
Partial<PendingPromptsRuntimeService & CommandExecutionRuntimeService>;
|
||||
@@ -306,14 +307,17 @@ export class HubServerTransport implements NativeHubTransport {
|
||||
}),
|
||||
);
|
||||
});
|
||||
this.sessionHost =
|
||||
options.sessionHost ??
|
||||
new LocalRuntimeHost({
|
||||
sessionService: new CoreSessionService(new SqliteSessionStore()),
|
||||
if (options.sessionHost) {
|
||||
this.sessionHost = options.sessionHost;
|
||||
} else {
|
||||
this.sessionStore = new SqliteSessionStore();
|
||||
this.sessionHost = new LocalRuntimeHost({
|
||||
sessionService: new CoreSessionService(this.sessionStore),
|
||||
fetch: options.fetch,
|
||||
logger: options.logger,
|
||||
telemetry: options.telemetry,
|
||||
});
|
||||
}
|
||||
this.sessionSearch = new SessionHistorySearchService(
|
||||
this.sessionHost,
|
||||
options.sessionSearchOptions ??
|
||||
@@ -764,7 +768,12 @@ export class HubServerTransport implements NativeHubTransport {
|
||||
await this.pluginCommands.dispose();
|
||||
await this.sessionSearch.dispose();
|
||||
await this.tasks.dispose();
|
||||
await this.sessionHost.dispose("hub_server_stop");
|
||||
try {
|
||||
await this.sessionHost.dispose("hub_server_stop");
|
||||
} finally {
|
||||
// The Hub owns the default store; injected runtimes own theirs.
|
||||
this.sessionStore?.close();
|
||||
}
|
||||
await this.schedules.dispose();
|
||||
if (this.cronService) {
|
||||
try {
|
||||
|
||||
@@ -2,6 +2,7 @@ import { mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { afterEach, beforeEach, expect, it, vi } from "vitest";
|
||||
import { SqliteSessionStore } from "../../services/storage/sqlite-session-store";
|
||||
import { localHubHasNoActiveSessions, NodeHubClient } from "../client";
|
||||
import { HubPluginClient } from "../client/plugin-client";
|
||||
import { createLocalHubScheduleRuntimeHandlers } from "../daemon/runtime-handlers";
|
||||
@@ -205,3 +206,20 @@ it("reports a marketplace install as busy without an attached chat", async () =>
|
||||
.payload?.idle,
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("closes the Hub-owned session database before removing its directory", async () => {
|
||||
const opened = vi.spyOn(SqliteSessionStore.prototype, "getRawDb");
|
||||
try {
|
||||
await transport.handleCommand({ version: "v1", command: "session.list" });
|
||||
const db = opened.mock.results.find(
|
||||
(result) => result.type === "return",
|
||||
)?.value;
|
||||
if (!db)
|
||||
throw new Error("Expected session.list to open the session database");
|
||||
await transport.stop();
|
||||
stopped = true;
|
||||
expect(() => db.prepare("SELECT 1").get()).toThrow();
|
||||
} finally {
|
||||
opened.mockRestore();
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user