Add env var support, error handling, and race protection
This commit is contained in:
parent
ef4b4b06e2
commit
9d9234173c
2 changed files with 19 additions and 5 deletions
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
try {
|
||||||
saveUpdate(this.name, update);
|
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}`);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue