Add env var support, error handling, and race protection

This commit is contained in:
Jared Miller 2026-01-27 21:28:51 -05:00
parent ef4b4b06e2
commit 9d9234173c
Signed by: shmup
GPG key ID: 22B5C6D66A38B06C
2 changed files with 19 additions and 5 deletions

View file

@ -10,7 +10,9 @@ import {
const PORT = Number(process.env.PORT) || 4040; const PORT = Number(process.env.PORT) || 4040;
// Initialize database // Initialize database
initDb("collabd.db"); const DB_PATH = process.env.COLLABD_DB || "collabd.db";
initDb(DB_PATH);
console.debug(`database initialized: ${DB_PATH}`);
function isValidRoomName(name: unknown): name is string { function isValidRoomName(name: unknown): name is string {
if (typeof name !== "string") return false; if (typeof name !== "string") return false;

View file

@ -1,7 +1,7 @@
import type { ServerWebSocket } from "bun"; import type { ServerWebSocket } from "bun";
import * as Y from "yjs"; import * as Y from "yjs";
import { getUpdates, saveUpdate } from "./db";
import { type AwarenessState, encode } from "./protocol"; import { type AwarenessState, encode } from "./protocol";
import { saveUpdate, getUpdates } from "./db";
export interface WsData { export interface WsData {
room: string | null; room: string | null;
@ -16,7 +16,7 @@ export class Session {
doc: Y.Doc; doc: Y.Doc;
clients: Set<Client> = new Set(); clients: Set<Client> = new Set();
constructor(public name: string) { constructor(public readonly name: string) {
this.doc = new Y.Doc(); this.doc = new Y.Doc();
} }
@ -50,8 +50,13 @@ export class Session {
applyUpdate(update: Uint8Array, from: Client) { applyUpdate(update: Uint8Array, from: Client) {
try { try {
Y.applyUpdate(this.doc, update); Y.applyUpdate(this.doc, update);
// Persist the update // Persist the update (log but don't fail on db errors)
saveUpdate(this.name, update); try {
saveUpdate(this.name, update);
} catch (err) {
console.error(`failed to persist update in room ${this.name}:`, err);
// Continue - memory state is still updated
}
// broadcast to others // broadcast to others
for (const client of this.clients) { for (const client of this.clients) {
if (client !== from) { if (client !== from) {
@ -114,6 +119,13 @@ export function getOrCreateSession(name: string): Session {
for (const update of updates) { for (const update of updates) {
Y.applyUpdate(session.doc, update); Y.applyUpdate(session.doc, update);
} }
// Double-check pattern - another request may have created session while we loaded
const existing = sessions.get(name);
if (existing) {
return existing;
}
sessions.set(name, session); sessions.set(name, session);
console.debug(`session created: ${name}`); console.debug(`session created: ${name}`);
} }