부하·장애 주입 테스트 스크립트, 테스트 전용 HTTP 제한 해제 옵션, chess.js 의존성

- scripts/loadtest.ts: 방 N개 × (선수 2 + 관전자) 연결, 방마다 2초에 한 수, 상대 수신까지 지연 p50/p95/p99,
  서버 CPU·메모리, --chaos 시 서버 SIGKILL → 재시작 → 재연결·수 유실 검사
- LOADTEST_NO_HTTP_LIMITS=1(https 주소에서는 무시)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
EJClaw
2026-10-04 05:07:43 +09:00
parent f81f20a4bf
commit f72be633f8
5 changed files with 219 additions and 5 deletions

View File

@@ -10,6 +10,8 @@ export interface Config {
/** Trust X-Forwarded-For (only when running behind our reverse proxy). */
trustProxy: boolean;
superadminDiscordIds: string[];
/** Load-test only: lift per-IP HTTP limits. Ignored for https origins. */
loadTestNoHttpLimits: boolean;
}
/** The site owner's Discord ID (docs/14-admin.md §2). */
@@ -33,6 +35,7 @@ export function loadConfig(env: Record<string, string | undefined> = process.env
sessionSecret: sessionSecret || 'dev-only-insecure-session-secret-change-me',
secureCookies: publicOrigin.startsWith('https://'),
trustProxy: env.TRUST_PROXY === '1',
loadTestNoHttpLimits: env.LOADTEST_NO_HTTP_LIMITS === '1' && !publicOrigin.startsWith('https://'),
superadminDiscordIds: (env.SUPERADMIN_DISCORD_IDS ?? DEFAULT_SUPERADMIN).split(',').map((s) => s.trim()).filter(Boolean),
};
}

View File

@@ -33,9 +33,10 @@ const OAUTH_COOKIE = 'oauth';
export function createHttpApp(d: HttpDeps) {
const app = new Hono<Env>();
const createLimiter = new WindowLimiter(10, 60_000);
const lookupLimiter = new WindowLimiter(30, 60_000);
const guestLimiter = new WindowLimiter(20, 60_000);
const lift = d.config.loadTestNoHttpLimits ? 1_000_000 : 1;
const createLimiter = new WindowLimiter(10 * lift, 60_000);
const lookupLimiter = new WindowLimiter(30 * lift, 60_000);
const guestLimiter = new WindowLimiter(20 * lift, 60_000);
const redirectUri = `${d.config.publicOrigin}/api/auth/discord/callback`;
const cookieOpts = (maxAgeMs: number) => ({