Archived
feat: add session daemon health lifecycle
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
# 07. Improve session daemon health and lifecycle
|
# 07. Improve session daemon health and lifecycle
|
||||||
|
|
||||||
Status: pending
|
Status: completed
|
||||||
|
|
||||||
Add health visibility and explicit lifecycle cleanup for the long-lived session daemon.
|
Add health visibility and explicit lifecycle cleanup for the long-lived session daemon.
|
||||||
|
|||||||
@@ -14,6 +14,20 @@ const eventHub = new SessionEventHub();
|
|||||||
const sessions = new PiSessionService(eventHub);
|
const sessions = new PiSessionService(eventHub);
|
||||||
registerSessionRoutes(app, sessions, eventHub);
|
registerSessionRoutes(app, sessions, eventHub);
|
||||||
|
|
||||||
|
app.get("/health", () => ({ ok: true, activeSessions: sessions.activeCount(), checkedAt: new Date().toISOString() }));
|
||||||
|
|
||||||
|
let shuttingDown = false;
|
||||||
|
async function shutdown(signal: NodeJS.Signals): Promise<void> {
|
||||||
|
if (shuttingDown) return;
|
||||||
|
shuttingDown = true;
|
||||||
|
app.log.info({ signal }, "shutting down session daemon");
|
||||||
|
await sessions.dispose();
|
||||||
|
await app.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
process.once("SIGINT", (signal) => { void shutdown(signal); });
|
||||||
|
process.once("SIGTERM", (signal) => { void shutdown(signal); });
|
||||||
|
|
||||||
const portValue = process.env["PI_WEB_SESSIOND_PORT"];
|
const portValue = process.env["PI_WEB_SESSIOND_PORT"];
|
||||||
const port = portValue !== undefined && portValue !== "" ? Number(portValue) : undefined;
|
const port = portValue !== undefined && portValue !== "" ? Number(portValue) : undefined;
|
||||||
const host = process.env["PI_WEB_SESSIOND_HOST"] ?? "127.0.0.1";
|
const host = process.env["PI_WEB_SESSIOND_HOST"] ?? "127.0.0.1";
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ export function registerSessionProxyRoutes(app: FastifyInstance, daemon = new Se
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
app.get("/api/sessiond/health", (_request, reply) => proxy({ method: "GET", url: "/api/health" }, reply));
|
||||||
|
|
||||||
app.get<{ Querystring: { cwd?: string } }>("/api/sessions", (request, reply) => proxy(request, reply));
|
app.get<{ Querystring: { cwd?: string } }>("/api/sessions", (request, reply) => proxy(request, reply));
|
||||||
app.post<{ Body: { cwd: string } }>("/api/sessions", (request, reply) => proxy(request, reply));
|
app.post<{ Body: { cwd: string } }>("/api/sessions", (request, reply) => proxy(request, reply));
|
||||||
app.get<{ Params: { sessionId: string } }>("/api/sessions/:sessionId/messages", (request, reply) => proxy(request, reply));
|
app.get<{ Params: { sessionId: string } }>("/api/sessions/:sessionId/messages", (request, reply) => proxy(request, reply));
|
||||||
|
|||||||
@@ -47,6 +47,22 @@ export class PiSessionService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
activeCount(): number {
|
||||||
|
return this.active.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
async dispose(): Promise<void> {
|
||||||
|
clearInterval(this.heartbeat);
|
||||||
|
const activeSessions = Array.from(new Set(this.active.values()));
|
||||||
|
this.active.clear();
|
||||||
|
this.activities.clear();
|
||||||
|
await Promise.all(activeSessions.map(async (active) => {
|
||||||
|
active.unsubscribe();
|
||||||
|
await active.runtime.session.abort();
|
||||||
|
await active.runtime.dispose();
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
async list(cwd: string): Promise<ClientSession[]> {
|
async list(cwd: string): Promise<ClientSession[]> {
|
||||||
const [sessions, archivedRecords] = await Promise.all([SessionManager.list(cwd), this.archiveStore.list()]);
|
const [sessions, archivedRecords] = await Promise.all([SessionManager.list(cwd), this.archiveStore.list()]);
|
||||||
const archivedById = new Map(archivedRecords.filter((record) => record.cwd === cwd).map((record) => [record.sessionId, record]));
|
const archivedById = new Map(archivedRecords.filter((record) => record.cwd === cwd).map((record) => [record.sessionId, record]));
|
||||||
|
|||||||
Reference in New Issue
Block a user