The template's lost-seat search has a limit of its own

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CCLa2PaEeCj8njQZSWGqHx
This commit is contained in:
Eric WagonerandClaude Fable 5.1 committed 2026-11-10 21:30:43 -05:00
1 parent 11a206e97d
commit 1a46d611a0
1 file changed
+4 -1
+4 -1
View File
@@ -97,6 +97,8 @@ const galleryVoices = new RateLimit(30, 10 * 60 * 1000);
const bells = new RateLimit(3, 60 * 60 * 1000); const bells = new RateLimit(3, 60 * 60 * 1000);
/** Claims on transfer phrases: a phrase is guessed, not brute-forced. */ /** Claims on transfer phrases: a phrase is guessed, not brute-forced. */
const claims = new RateLimit(10, 10 * 60 * 1000); const claims = new RateLimit(10, 10 * 60 * 1000);
/** Searches for lost seats: each reads every table written to lately, and a person loses their seats rarely. */
const searches = new RateLimit(5, 10 * 60 * 1000);
const MAX_AUDIENCE = 30; const MAX_AUDIENCE = 30;
/** How often each socket is asked to answer; one silent through a whole round is a browser gone, and is closed. */ /** How often each socket is asked to answer; one silent through a whole round is a browser gone, and is closed. */
const PING_MS = Number(process.env.PING_MS ?? 30_000); const PING_MS = Number(process.env.PING_MS ?? 30_000);
@@ -109,6 +111,7 @@ setInterval(() => {
galleryVoices.prune(); galleryVoices.prune();
bells.prune(); bells.prune();
claims.prune(); claims.prune();
searches.prune();
if (n) console.log(`evicted ${n} idle room${n === 1 ? '' : 's'} from memory; ${rooms.loaded} loaded`); if (n) console.log(`evicted ${n} idle room${n === 1 ? '' : 's'} from memory; ${rooms.loaded} loaded`);
}, 60 * 60 * 1000).unref(); }, 60 * 60 * 1000).unref();
@@ -347,7 +350,7 @@ async function handle(req: IncomingMessage, res: ServerResponse): Promise<void>
return send(res, 200, { seats }); return send(res, 200, { seats });
} }
if (parts[2] === 'find' && parts.length === 3) { if (parts[2] === 'find' && parts.length === 3) {
if (!claims.allow(clientOf(req))) throw new RoomError('Too many searches from here just now; try again later.', 429); if (!searches.allow(clientOf(req))) throw new RoomError('Too many searches from here just now; try again later.', 429);
const found = rooms.findSeats(String(body.name ?? ''), addrOf(req), typeof body.roomId === 'string' ? body.roomId : undefined); const found = rooms.findSeats(String(body.name ?? ''), addrOf(req), typeof body.roomId === 'string' ? body.roomId : undefined);
// The seats given back are banked at once, so the cookie and the browser agree. // The seats given back are banked at once, so the cookie and the browser agree.
if (found.seated.length) bankSeats(req, res, provenBank(req, found.seated, [])); if (found.seated.length) bankSeats(req, res, provenBank(req, found.seated, []));