File size: 1,120 Bytes
8ec75dd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
const TTL_MS = 30 * 60 * 1000;
const CLEAN_INTERVAL_MS = 5 * 60 * 1000;

interface EngineEntry {
  url: string;
  expiresAt: number;
}

const sessions = new Map<string, EngineEntry>();
let cleanupTimer: ReturnType<typeof setInterval> | null = null;

export function registerSession(sessionId: string, url: string): void {
  sessions.set(sessionId, { url, expiresAt: Date.now() + TTL_MS });
  ensureCleanupTimer();
}

export function getSessionUrl(sessionId: string): string | null {
  const entry = sessions.get(sessionId);
  if (!entry) return null;
  if (Date.now() > entry.expiresAt) {
    sessions.delete(sessionId);
    return null;
  }
  return entry.url;
}

// Stems live on a user's remote engine, so a dead session is just a stale
// tunnel url — sweep it to keep the map from growing unbounded.
function purgeExpired(): void {
  const now = Date.now();
  for (const [id, entry] of sessions) {
    if (now > entry.expiresAt) sessions.delete(id);
  }
}

function ensureCleanupTimer(): void {
  if (cleanupTimer) return;
  cleanupTimer = setInterval(purgeExpired, CLEAN_INTERVAL_MS);
  cleanupTimer.unref?.();
}