86 lines
2.4 KiB
TypeScript
86 lines
2.4 KiB
TypeScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
|
|
test('turn runtime: session A stream survives session B switch', () => {
|
|
type TurnRuntime = {
|
|
clientTurnId: string;
|
|
sessionId: string;
|
|
status: string;
|
|
controller: { aborted: boolean };
|
|
};
|
|
const store = new Map<string, Map<string, TurnRuntime>>();
|
|
|
|
const register = (rt: TurnRuntime) => {
|
|
if (!store.has(rt.sessionId)) store.set(rt.sessionId, new Map());
|
|
store.get(rt.sessionId)!.set(rt.clientTurnId, rt);
|
|
};
|
|
|
|
const isSessionThinking = (sessionId: string) => {
|
|
const m = store.get(sessionId);
|
|
if (!m) return false;
|
|
for (const rt of m.values()) {
|
|
if (rt.status === 'pending' || rt.status === 'streaming') return true;
|
|
}
|
|
return false;
|
|
};
|
|
|
|
register({
|
|
clientTurnId: 'turn-a',
|
|
sessionId: 'session-A',
|
|
status: 'streaming',
|
|
controller: { aborted: false },
|
|
});
|
|
|
|
assert.equal(isSessionThinking('session-A'), true);
|
|
assert.equal(isSessionThinking('session-B'), false);
|
|
|
|
register({
|
|
clientTurnId: 'turn-b',
|
|
sessionId: 'session-B',
|
|
status: 'pending',
|
|
controller: { aborted: false },
|
|
});
|
|
|
|
assert.equal(isSessionThinking('session-A'), true);
|
|
assert.equal(isSessionThinking('session-B'), true);
|
|
});
|
|
|
|
test('abortAllSessions aborts controllers across all sessions', () => {
|
|
type TurnRuntime = {
|
|
clientTurnId: string;
|
|
sessionId: string;
|
|
status: string;
|
|
controller: { aborted: boolean; abort: () => void };
|
|
};
|
|
const store = new Map<string, Map<string, TurnRuntime>>();
|
|
|
|
const makeController = () => {
|
|
const c = { aborted: false, abort() { c.aborted = true; } };
|
|
return c;
|
|
};
|
|
|
|
const register = (rt: TurnRuntime) => {
|
|
if (!store.has(rt.sessionId)) store.set(rt.sessionId, new Map());
|
|
store.get(rt.sessionId)!.set(rt.clientTurnId, rt);
|
|
};
|
|
|
|
const abortAllSessions = () => {
|
|
for (const sessionMap of store.values()) {
|
|
for (const rt of sessionMap.values()) {
|
|
if (rt.status === 'pending' || rt.status === 'streaming') {
|
|
rt.controller.abort();
|
|
rt.status = 'cancelled';
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
const a = makeController();
|
|
const b = makeController();
|
|
register({ clientTurnId: 't1', sessionId: 's1', status: 'streaming', controller: a });
|
|
register({ clientTurnId: 't2', sessionId: 's2', status: 'pending', controller: b });
|
|
abortAllSessions();
|
|
assert.equal(a.aborted, true);
|
|
assert.equal(b.aborted, true);
|
|
});
|