diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 807502598..500c58c90 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -112,6 +112,7 @@ jobs: GHCR_USERNAME: ${{ vars.GHCR_USERNAME }} ENV: ${{ inputs.target_domain == 'openfront.io' && 'prod' || 'staging' }} HOST: ${{ github.event_name == 'workflow_dispatch' && inputs.target_host || 'staging' }} + NUM_WORKERS: ${{ vars.NUM_WORKERS }} OTEL_EXPORTER_OTLP_ENDPOINT: ${{ secrets.OTEL_EXPORTER_OTLP_ENDPOINT }} OTEL_AUTH_HEADER: ${{ secrets.OTEL_AUTH_HEADER }} TURNSTILE_SECRET_KEY: ${{ secrets.TURNSTILE_SECRET_KEY }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6a09e6072..f2221479d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -70,6 +70,7 @@ jobs: GHCR_USERNAME: ${{ vars.GHCR_USERNAME }} DOMAIN: ${{ vars.DOMAIN }} IMAGE_ID: ${{ needs.build.outputs.IMAGE_ID }} + NUM_WORKERS: ${{ vars.NUM_WORKERS }} OTEL_EXPORTER_OTLP_ENDPOINT: ${{ secrets.OTEL_EXPORTER_OTLP_ENDPOINT }} OTEL_AUTH_HEADER: ${{ secrets.OTEL_AUTH_HEADER }} TURNSTILE_SECRET_KEY: ${{ secrets.TURNSTILE_SECRET_KEY }} @@ -121,6 +122,7 @@ jobs: GHCR_USERNAME: ${{ vars.GHCR_USERNAME }} DOMAIN: ${{ vars.DOMAIN }} IMAGE_ID: ${{ needs.build.outputs.IMAGE_ID }} + NUM_WORKERS: ${{ vars.NUM_WORKERS }} OTEL_EXPORTER_OTLP_ENDPOINT: ${{ secrets.OTEL_EXPORTER_OTLP_ENDPOINT }} OTEL_AUTH_HEADER: ${{ secrets.OTEL_AUTH_HEADER }} TURNSTILE_SECRET_KEY: ${{ secrets.TURNSTILE_SECRET_KEY }} @@ -172,6 +174,7 @@ jobs: GHCR_USERNAME: ${{ vars.GHCR_USERNAME }} DOMAIN: ${{ vars.DOMAIN }} IMAGE_ID: ${{ needs.build.outputs.IMAGE_ID }} + NUM_WORKERS: ${{ vars.NUM_WORKERS }} OTEL_EXPORTER_OTLP_ENDPOINT: ${{ secrets.OTEL_EXPORTER_OTLP_ENDPOINT }} OTEL_AUTH_HEADER: ${{ secrets.OTEL_AUTH_HEADER }} TURNSTILE_SECRET_KEY: ${{ secrets.TURNSTILE_SECRET_KEY }} @@ -223,6 +226,7 @@ jobs: GHCR_USERNAME: ${{ vars.GHCR_USERNAME }} DOMAIN: ${{ vars.DOMAIN }} IMAGE_ID: ${{ needs.build.outputs.IMAGE_ID }} + NUM_WORKERS: ${{ vars.NUM_WORKERS }} OTEL_EXPORTER_OTLP_ENDPOINT: ${{ secrets.OTEL_EXPORTER_OTLP_ENDPOINT }} OTEL_AUTH_HEADER: ${{ secrets.OTEL_AUTH_HEADER }} TURNSTILE_SECRET_KEY: ${{ secrets.TURNSTILE_SECRET_KEY }} diff --git a/deploy.sh b/deploy.sh index 6e0c6727a..bf48d1765 100755 --- a/deploy.sh +++ b/deploy.sh @@ -140,6 +140,7 @@ TURNSTILE_SECRET_KEY=$TURNSTILE_SECRET_KEY API_KEY=$API_KEY DOMAIN=$DOMAIN SUBDOMAIN=$SUBDOMAIN +NUM_WORKERS=$NUM_WORKERS OTEL_EXPORTER_OTLP_ENDPOINT=$OTEL_EXPORTER_OTLP_ENDPOINT OTEL_AUTH_HEADER=$OTEL_AUTH_HEADER EOL diff --git a/example.env b/example.env index 01cb270ea..d366e978c 100644 --- a/example.env +++ b/example.env @@ -14,6 +14,9 @@ DOMAIN=your-domain.com # API Key API_KEY=your_api_key_here +# Required for non-dev: server worker process count (defaults to 2 in dev) +NUM_WORKERS=number_of_workers + # Server Hosts SERVER_HOST_STAGING=123.456.78.90 SERVER_HOST_FALK1=123.456.78.91 diff --git a/src/core/configuration/DefaultConfig.ts b/src/core/configuration/DefaultConfig.ts index 4a8f3d8c5..e3cc0da2c 100644 --- a/src/core/configuration/DefaultConfig.ts +++ b/src/core/configuration/DefaultConfig.ts @@ -164,7 +164,17 @@ export abstract class DefaultServerConfig implements ServerConfig { } return token; } - abstract numWorkers(): number; + numWorkers(): number { + const raw = Env.NUM_WORKERS; + if (!raw) { + throw new Error("NUM_WORKERS not set"); + } + const parsed = Number(raw); + if (!Number.isFinite(parsed) || parsed <= 0) { + throw new Error(`Invalid NUM_WORKERS value "${raw}"`); + } + return Math.floor(parsed); + } abstract env(): GameEnv; turnIntervalMs(): number { return 100; diff --git a/src/core/configuration/DevConfig.ts b/src/core/configuration/DevConfig.ts index 09c0adaa6..b7d252816 100644 --- a/src/core/configuration/DevConfig.ts +++ b/src/core/configuration/DevConfig.ts @@ -27,7 +27,6 @@ export class DevServerConfig extends DefaultServerConfig { gameCreationRate(): number { return 5 * 1000; } - numWorkers(): number { return 2; } diff --git a/src/core/configuration/Env.ts b/src/core/configuration/Env.ts index 655202b34..31f873f00 100644 --- a/src/core/configuration/Env.ts +++ b/src/core/configuration/Env.ts @@ -89,4 +89,7 @@ export const Env = { get ADMIN_TOKEN() { return getEnv("ADMIN_TOKEN"); }, + get NUM_WORKERS() { + return getEnv("NUM_WORKERS"); + }, }; diff --git a/src/core/configuration/PreprodConfig.ts b/src/core/configuration/PreprodConfig.ts index e9346cc26..361d19af7 100644 --- a/src/core/configuration/PreprodConfig.ts +++ b/src/core/configuration/PreprodConfig.ts @@ -5,9 +5,6 @@ export const preprodConfig = new (class extends DefaultServerConfig { env(): GameEnv { return GameEnv.Preprod; } - numWorkers(): number { - return 2; - } turnstileSiteKey(): string { return "0x4AAAAAAB7QetxHwRCKw-aP"; } diff --git a/src/core/configuration/ProdConfig.ts b/src/core/configuration/ProdConfig.ts index 198dd8007..310302fce 100644 --- a/src/core/configuration/ProdConfig.ts +++ b/src/core/configuration/ProdConfig.ts @@ -2,9 +2,6 @@ import { GameEnv } from "./Config"; import { DefaultServerConfig } from "./DefaultConfig"; export const prodConfig = new (class extends DefaultServerConfig { - numWorkers(): number { - return 20; - } env(): GameEnv { return GameEnv.Prod; } diff --git a/startup.sh b/startup.sh index 05b122a23..54000c89b 100644 --- a/startup.sh +++ b/startup.sh @@ -8,6 +8,12 @@ if [ -z "$CF_API_TOKEN" ] || [ -z "$CF_ACCOUNT_ID" ] || [ -z "$SUBDOMAIN" ] || [ exit 1 fi +# Require NUM_WORKERS for non-dev environments. +if [ "${GAME_ENV:-dev}" != "dev" ] && [ -z "$NUM_WORKERS" ]; then + echo "Error: NUM_WORKERS must be set for non-dev environments" + exit 1 +fi + # Generate a unique tunnel name using timestamp TIMESTAMP=$(date +%Y%m%d%H%M%S) TUNNEL_NAME="${SUBDOMAIN}-tunnel-${TIMESTAMP}"