mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-25 21:34:36 +00:00
c55ea6bb5a
## What Game creation no longer requires the caller to pick the `gameID` or compute its owning worker. The client POSTs to a prefix-less `/api/create_game`; **nginx (prod) and the vite dev proxy randomly route it to a worker**, which **mints an id that hashes back to itself** and returns it along with its `workerIndex`. ## Why it stays correct The minted id still hashes to the creating worker (via the existing `generateGameIdForWorker`), so everything downstream that derives the worker from the gameID — websocket connect, share URL, join flow — keeps working unchanged. The only thing that moved is *who picks the id and worker*. ## Changes - **`src/server/Worker.ts`** — factor create into a shared `createGameForId`; add `POST /api/create_game` (no id) that mints a self-owned id and returns `gameInfo` + `workerIndex`/`workerPath`. The existing `POST /api/create_game/:id` stays. - **`nginx.conf`** — `location = /api/create_game` proxies to a `random` worker upstream. - **`generate-nginx-upstream.sh` + `Dockerfile`** — the entrypoint generates that upstream from `NUM_WORKERS` at container **start** time. `NUM_WORKERS` isn't known at image build time (the image is built once and deployed with different env), so it can't be baked into `nginx.conf` — hence runtime generation of exactly the live worker ports (no dead-server padding). - **`vite.config.ts`** — dev-only middleware forwards `POST /api/create_game` to a random worker. Vite's `http-proxy` can't pick a per-request random target, so this is a small middleware plugin (same pattern as the existing `serveProprietaryDir`), registered before the `/api` proxy. - **`src/client/HostLobbyModal.ts`** — stop generating the id client-side; use the server's. ## Behavior change to note The host's share link used to be copied **instantly** from a client-generated id. Now the id comes from the server, so the copy waits one create round-trip — I moved the URL build/copy into the create `.then` (and kept the failure path that clears the clipboard). Brief empty-link state in the modal until create resolves. ## Verification - tsc + eslint clean; full suite green (1543 tests). - nginx additions validated with `nginx -t` in isolation (the full file references container-only paths like `/etc/nginx/mime.types`); upstream + `proxy_pass` resolve. - `generate-nginx-upstream.sh` tested with `NUM_WORKERS` set and unset (defaults to 1). Not yet exercised live end-to-end (needs a dev-server restart — `vite.config.ts` + `Worker.ts` changes aren't hot-reloaded). 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
40 lines
1.2 KiB
Bash
Executable File
40 lines
1.2 KiB
Bash
Executable File
#!/bin/sh
|
|
# generate-nginx-upstream.sh
|
|
#
|
|
# Generates the per-worker nginx config from NUM_WORKERS at container start
|
|
# (NUM_WORKERS arrives via the runtime env file and is not known when the image
|
|
# is built, so it can't be baked into nginx.conf). Emits two things, both in the
|
|
# http context, into a single conf.d file:
|
|
#
|
|
# 1. upstream openfront_workers - random-balanced across the live workers, so
|
|
# nginx can spread requests (e.g. POST /api/create_game) without the caller
|
|
# knowing the worker count.
|
|
# 2. map $worker $worker_port - worker index -> port (3001 + index), so the
|
|
# /wN/ locations route without a hand-maintained if-ladder.
|
|
#
|
|
# Usage: generate-nginx-upstream.sh [output_path]
|
|
set -eu
|
|
|
|
OUT="${1:-/etc/nginx/conf.d/00-workers.conf}"
|
|
n="${NUM_WORKERS:-1}"
|
|
|
|
{
|
|
echo 'upstream openfront_workers {'
|
|
echo ' random;'
|
|
i=0
|
|
while [ "$i" -lt "$n" ]; do
|
|
echo " server 127.0.0.1:$((3001 + i));"
|
|
i=$((i + 1))
|
|
done
|
|
echo '}'
|
|
echo ''
|
|
echo 'map $worker $worker_port {'
|
|
echo ' default 3001;'
|
|
i=0
|
|
while [ "$i" -lt "$n" ]; do
|
|
echo " $i $((3001 + i));"
|
|
i=$((i + 1))
|
|
done
|
|
echo '}'
|
|
} > "$OUT"
|