Skip to content

Commit 3311202

Browse files
committed
added session life cycle management
1 parent 7f4bc79 commit 3311202

2 files changed

Lines changed: 74 additions & 0 deletions

File tree

src/exec/session.ts

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { runtimeStore } from "../runtime/store.js";
2+
import { cleanupVm } from "../runtime/cleanup.js";
3+
import { sessionLogger } from "../utils/logger.js";
4+
5+
export interface Session {
6+
sessionId: string;
7+
createdAt: number;
8+
lastActivityAt: number;
9+
state: "creating" | "active" | "destroying";
10+
}
11+
12+
const sessions = new Map<string, Session>();
13+
14+
export function getSession(sessionId: string): Session | undefined {
15+
return sessions.get(sessionId);
16+
}
17+
18+
export function createSession(sessionId: string): Session {
19+
const session: Session = {
20+
sessionId,
21+
createdAt: Date.now(),
22+
lastActivityAt: Date.now(),
23+
state: "creating",
24+
};
25+
sessions.set(sessionId, session);
26+
return session;
27+
}
28+
29+
export function touchSession(sessionId: string): void {
30+
const session = sessions.get(sessionId);
31+
if (session) session.lastActivityAt = Date.now();
32+
}
33+
34+
export async function destroySession(sessionId: string): Promise<boolean> {
35+
const session = sessions.get(sessionId);
36+
if (!session) return false;
37+
38+
session.state = "destroying";
39+
40+
const fn = runtimeStore.functions.get(sessionId);
41+
if (fn) {
42+
for (const vm of [...fn.vms]) {
43+
await cleanupVm(fn, vm);
44+
}
45+
runtimeStore.functions.delete(sessionId);
46+
}
47+
48+
sessions.delete(sessionId);
49+
sessionLogger.info({ sessionId }, "session destroyed");
50+
return true;
51+
}
52+
53+
export function getActiveSessions(): number {
54+
return sessions.size;
55+
}
56+
57+
export function getAllSessions(): Session[] {
58+
return [...sessions.values()];
59+
}
60+
61+
export function startSessionReaper(ttlMs: number = 30 * 60 * 1000): void {
62+
setInterval(() => {
63+
const now = Date.now();
64+
for (const [id, session] of sessions) {
65+
if (now - session.lastActivityAt > ttlMs && session.state === "active") {
66+
sessionLogger.info({ sessionId: id, idleMs: now - session.lastActivityAt }, "reaping idle session");
67+
destroySession(id).catch(err => {
68+
sessionLogger.error({ sessionId: id, err }, "session reap failed");
69+
});
70+
}
71+
}
72+
}, 60_000);
73+
}

src/utils/logger.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export const vmManagerLogger = logger.child({ module: "vm-manager" });
3333
export const transportLogger = logger.child({ module: "transport" });
3434
export const protocolLogger = logger.child({ module: "protocol" });
3535
export const cleanupLogger = logger.child({ module: "cleanup" });
36+
export const sessionLogger = logger.child({module: "session"})
3637

3738
export const httpLoggerOptions: Options = {
3839
logger: logger.child({ module: "http" }),

0 commit comments

Comments
 (0)