Skip to content

Commit 1872dec

Browse files
committed
QueueDO -> SessionManager and assorted fixes
1 parent 434b057 commit 1872dec

3 files changed

Lines changed: 28 additions & 14 deletions

File tree

web/frontend/src/lib/Console.svelte

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,10 +186,12 @@
186186
} catch (e) { console.error("Failed to process message", e); }
187187
};
188188
189-
socket.onclose = () => {
190-
if (cleanClose) {
189+
socket.onclose = (event: CloseEvent) => {
190+
if (cleanClose || event.code === 1000) {
191191
virtualConsole.addLines(["\u001b[90mConnection closed.\u001b[0m"]);
192+
sessionState.set("closed");
192193
commandInput.disabled = true;
194+
appendEndedCard(outputContainer);
193195
return;
194196
}
195197
@@ -213,7 +215,7 @@
213215
}
214216
215217
function attemptReconnect() {
216-
if (!socket || cleanClose) return;
218+
if (!socket || cleanClose || $sessionState === "closed") return;
217219
const wsUrl = socket.url;
218220
socket = new WebSocket(wsUrl);
219221
setupWebSocketHandlers();

web/src/index.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export interface Env {
2828
GMOD_SIXTYFOUR: DurableObjectNamespace;
2929
GMOD_PRERELEASE: DurableObjectNamespace;
3030
GMOD_DEV: DurableObjectNamespace;
31-
QUEUE_DO: DurableObjectNamespace<QueueDO>;
31+
SESSION_MANAGER: DurableObjectNamespace<SessionManager>;
3232
LOG_BUCKET: R2Bucket;
3333
DISCORD_WEBHOOK_URL?: string;
3434
}
@@ -62,8 +62,8 @@ export class BaseSession extends Container<Env> {
6262

6363
private async fetchCapacitySnapshot(): Promise<CapacitySnapshot | undefined> {
6464
try {
65-
const queueDO = this.env.QUEUE_DO.get(this.env.QUEUE_DO.idFromName("global-queue"));
66-
const res = await queueDO.fetch(`http://do/internal/capacity?branch=${encodeURIComponent(this.branch)}`);
65+
const manager =this.env.SESSION_MANAGER.get(this.env.SESSION_MANAGER.idFromName("global-queue"));
66+
const res = await manager.fetch(`http://do/internal/capacity?branch=${encodeURIComponent(this.branch)}`);
6767
if (!res.ok) return undefined;
6868
return await res.json<CapacitySnapshot>();
6969
} catch (e) {
@@ -86,6 +86,11 @@ export class BaseSession extends Container<Env> {
8686
this.logLineCount = 0;
8787
this.scriptBuffer = {};
8888
this.scriptCount = 0;
89+
90+
ctx.blockConcurrencyWhile(async () => {
91+
const closed = await ctx.storage.get<boolean>("closed");
92+
if (closed) this.sessionState = "CLOSED";
93+
});
8994
}
9095

9196
override async fetch(request: Request): Promise<Response> {
@@ -387,6 +392,7 @@ export class BaseSession extends Container<Env> {
387392
async closeSession(reason: CloseReason) {
388393
if (this.sessionState === "CLOSED") return;
389394
this.sessionState = "CLOSED";
395+
await this.ctx.storage.put("closed", true);
390396
const endedAt = Date.now();
391397
if (this.sessionMetadata) {
392398
this.sessionMetadata.endedAt = endedAt;
@@ -428,8 +434,8 @@ export class BaseSession extends Container<Env> {
428434
}
429435

430436
async notifyQueueManagerOfClosure() {
431-
const queueDO = this.env.QUEUE_DO.get(this.env.QUEUE_DO.idFromName("global-queue"));
432-
await queueDO.fetch("http://do/api/session-closed", {
437+
const manager =this.env.SESSION_MANAGER.get(this.env.SESSION_MANAGER.idFromName("global-queue"));
438+
await manager.fetch("http://do/api/session-closed", {
433439
method: "POST",
434440
headers: {"Content-Type": "application/json"},
435441
body: JSON.stringify({ sessionId: this.ctx.id.name! })
@@ -560,7 +566,7 @@ const QUEUE_ENTRY_TTL = 5 * 60 * 1000;
560566
const RESOLVED_TICKET_TTL = 2 * 60 * 1000;
561567
const QUEUE_CLEANUP_INTERVAL = 30 * 1000;
562568

563-
export class QueueDO extends DurableObject<Env> {
569+
export class SessionManager extends DurableObject<Env> {
564570
activeSessions: Map<string, string>; // sessionId → type
565571
sessionIPs: Map<string, string>; // sessionId → hashed IP
566572
waitingQueue: QueueEntry[];
@@ -838,7 +844,7 @@ export class QueueDO extends DurableObject<Env> {
838844
}), { headers: { "Content-Type": "application/json" } });
839845
}
840846

841-
return new Response("Not found in QueueDO", { status: 404 });
847+
return new Response("Not found", { status: 404 });
842848
}
843849

844850
async alarm() {
@@ -878,8 +884,8 @@ export default {
878884
const forwarded = withObsHeader(request);
879885

880886
if (url.pathname.startsWith("/api/")) {
881-
const queueDO = env.QUEUE_DO.get(env.QUEUE_DO.idFromName("global-queue"));
882-
return queueDO.fetch(forwarded);
887+
const manager =env.SESSION_MANAGER.get(env.SESSION_MANAGER.idFromName("global-queue"));
888+
return manager.fetch(forwarded);
883889
}
884890

885891
if (url.pathname.startsWith("/ws/")) {

web/wrangler.jsonc

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
],
4949
"durable_objects": {
5050
"bindings": [
51-
{ "name": "QUEUE_DO", "class_name": "QueueDO" },
51+
{ "name": "SESSION_MANAGER", "class_name": "SessionManager" },
5252
{ "name": "GMOD_PUBLIC", "class_name": "GmodPublic" },
5353
{ "name": "GMOD_SIXTYFOUR", "class_name": "GmodSixtyFour" },
5454
{ "name": "GMOD_PRERELEASE", "class_name": "GmodPrerelease" },
@@ -57,14 +57,20 @@
5757
},
5858
"migrations": [
5959
{
60-
"tag": "v1",
60+
"tag": "v2",
6161
"new_classes": [
6262
"QueueDO",
6363
"GmodPublic",
6464
"GmodSixtyFour",
6565
"GmodPrerelease",
6666
"GmodDev"
6767
]
68+
},
69+
{
70+
"tag": "v3",
71+
"renamed_classes": [
72+
{ "from": "QueueDO", "to": "SessionManager" }
73+
]
6874
}
6975
]
7076
}

0 commit comments

Comments
 (0)