Files
TJWaterAgent/dist/session/registry.js
T

58 lines
1.7 KiB
JavaScript

import crypto from "node:crypto";
export class SessionRegistry {
ttlMs;
bindings = new Map();
constructor(ttlSeconds) {
this.ttlMs = ttlSeconds * 1000;
}
upsert(context, sessionId) {
const binding = {
clientSessionId: context.clientSessionId,
sessionId,
lastUsedAt: Date.now(),
};
this.bindings.set(this.makeKey(context), binding);
return binding;
}
get(context) {
const key = this.makeKey(context);
const binding = this.bindings.get(key);
if (!binding) {
return null;
}
if (Date.now() - binding.lastUsedAt > this.ttlMs) {
this.bindings.delete(key);
return null;
}
binding.lastUsedAt = Date.now();
return binding;
}
count() {
this.evictExpired();
return this.bindings.size;
}
evictExpired() {
const expired = [];
const now = Date.now();
for (const [key, binding] of this.bindings.entries()) {
if (now - binding.lastUsedAt > this.ttlMs) {
expired.push(binding.sessionId);
this.bindings.delete(key);
}
}
return expired;
}
makeKey(context) {
// 会话隔离不能只看前端 session_id;同一浏览器会话切换用户或项目时必须映射到不同 opencode session。
const digest = crypto
.createHash("sha256")
.update([
context.clientSessionId,
context.accessToken ?? "",
context.projectId ?? "",
].join("|"))
.digest("hex");
return digest;
}
}