From 2c9fc7307e14a6256e22360b75eeb28cc5316cf3 Mon Sep 17 00:00:00 2001 From: evanpelle Date: Wed, 19 Mar 2025 15:42:47 -0700 Subject: [PATCH] fix config circular dependency (#296) --- src/client/ClientGameRunner.ts | 3 +- src/client/HostLobbyModal.ts | 6 +-- src/client/JoinPrivateLobbyModal.ts | 2 +- src/client/Main.ts | 2 +- src/core/GameRunner.ts | 2 +- src/core/configuration/Config.ts | 64 -------------------------- src/core/configuration/ConfigLoader.ts | 64 ++++++++++++++++++++++++++ src/server/Archive.ts | 6 +-- src/server/Master.ts | 2 +- src/server/MasterMetrics.ts | 2 +- src/server/Worker.ts | 6 +-- src/server/WorkerMetrics.ts | 2 +- src/server/gatekeeper | 2 +- 13 files changed, 79 insertions(+), 84 deletions(-) create mode 100644 src/core/configuration/ConfigLoader.ts diff --git a/src/client/ClientGameRunner.ts b/src/client/ClientGameRunner.ts index 4eb89980a..b281d3965 100644 --- a/src/client/ClientGameRunner.ts +++ b/src/client/ClientGameRunner.ts @@ -26,7 +26,8 @@ import { } from "../core/game/GameUpdates"; import { WorkerClient } from "../core/worker/WorkerClient"; import { consolex, initRemoteSender } from "../core/Consolex"; -import { getConfig, ServerConfig } from "../core/configuration/Config"; +import { ServerConfig } from "../core/configuration/Config"; +import { getConfig } from "../core/configuration/ConfigLoader"; import { GameView, PlayerView } from "../core/game/GameView"; import { GameUpdateViewData } from "../core/game/GameUpdates"; import { UserSettings } from "../core/game/UserSettings"; diff --git a/src/client/HostLobbyModal.ts b/src/client/HostLobbyModal.ts index d59d5c845..c356991fa 100644 --- a/src/client/HostLobbyModal.ts +++ b/src/client/HostLobbyModal.ts @@ -8,10 +8,8 @@ import { DifficultyDescription } from "./components/Difficulties"; import "./components/Maps"; import randomMap from "../../resources/images/RandomMap.png"; import { generateID } from "../core/Util"; -import { - getConfig, - getServerConfigFromClient, -} from "../core/configuration/Config"; +import { getServerConfigFromClient } from "../core/configuration/ConfigLoader"; +import { getConfig } from "../core/configuration/ConfigLoader"; import { JoinLobbyEvent } from "./Main"; @customElement("host-lobby-modal") diff --git a/src/client/JoinPrivateLobbyModal.ts b/src/client/JoinPrivateLobbyModal.ts index b99892ad2..ffd4268de 100644 --- a/src/client/JoinPrivateLobbyModal.ts +++ b/src/client/JoinPrivateLobbyModal.ts @@ -3,7 +3,7 @@ import { customElement, query, state } from "lit/decorators.js"; import { consolex } from "../core/Consolex"; import { GameMapType, GameType } from "../core/game/Game"; import { GameInfo, GameRecord } from "../core/Schemas"; -import { getServerConfigFromClient } from "../core/configuration/Config"; +import { getServerConfigFromClient } from "../core/configuration/ConfigLoader"; import { JoinLobbyEvent } from "./Main"; @customElement("join-private-lobby-modal") diff --git a/src/client/Main.ts b/src/client/Main.ts index 274546b5b..b77129bc3 100644 --- a/src/client/Main.ts +++ b/src/client/Main.ts @@ -21,7 +21,7 @@ import { DarkModeButton } from "./DarkModeButton"; import "./GoogleAdElement"; import { HelpModal } from "./HelpModal"; import { GameType } from "../core/game/Game"; -import { getServerConfigFromClient } from "../core/configuration/Config"; +import { getServerConfigFromClient } from "../core/configuration/ConfigLoader"; import GoogleAdElement from "./GoogleAdElement"; import { GameConfig, GameInfo, GameRecord } from "../core/Schemas"; diff --git a/src/core/GameRunner.ts b/src/core/GameRunner.ts index 45edfb8ad..469d1c2b4 100644 --- a/src/core/GameRunner.ts +++ b/src/core/GameRunner.ts @@ -1,6 +1,6 @@ import { utcDay } from "d3"; import { placeName } from "../client/graphics/NameBoxCalculator"; -import { getConfig } from "./configuration/Config"; +import { getConfig } from "./configuration/ConfigLoader"; import { EventBus } from "./EventBus"; import { Executor } from "./execution/ExecutionManager"; import { WinCheckExecution } from "./execution/WinCheckExecution"; diff --git a/src/core/configuration/Config.ts b/src/core/configuration/Config.ts index dad9064bf..0116b6992 100644 --- a/src/core/configuration/Config.ts +++ b/src/core/configuration/Config.ts @@ -12,81 +12,17 @@ import { UnitType, } from "../game/Game"; import { Colord, colord } from "colord"; -import { preprodConfig } from "./PreprodConfig"; -import { prodConfig } from "./ProdConfig"; -import { consolex } from "../Consolex"; import { GameConfig, GameID } from "../Schemas"; -import { DefaultConfig } from "./DefaultConfig"; -import { DevConfig, DevServerConfig } from "./DevConfig"; import { GameMap, TileRef } from "../game/GameMap"; import { PlayerView } from "../game/GameView"; import { UserSettings } from "../game/UserSettings"; -let cachedSC: ServerConfig = null; - export enum GameEnv { Dev, Preprod, Prod, } -export async function getConfig( - gameConfig: GameConfig, - userSettings: UserSettings | null = null, -): Promise { - const sc = await getServerConfigFromClient(); - switch (sc.env()) { - case GameEnv.Dev: - return new DevConfig(sc, gameConfig, userSettings); - case GameEnv.Preprod: - case GameEnv.Prod: - consolex.log("using prod config"); - return new DefaultConfig(sc, gameConfig, userSettings); - default: - throw Error(`unsupported server configuration: ${process.env.GAME_ENV}`); - } -} - -export async function getServerConfigFromClient(): Promise { - if (cachedSC) { - return cachedSC; - } - const response = await fetch("/api/env"); - - if (!response.ok) { - throw new Error( - `Failed to fetch server config: ${response.status} ${response.statusText}`, - ); - } - const config = await response.json(); - // Log the retrieved configuration - console.log("Server config loaded:", config); - - cachedSC = getServerConfig(config.game_env); - return cachedSC; -} - -export function getServerConfigFromServer(): ServerConfig { - const gameEnv = process.env.GAME_ENV; - return getServerConfig(gameEnv); -} - -function getServerConfig(gameEnv: string) { - switch (gameEnv) { - case "dev": - consolex.log("using dev server config"); - return new DevServerConfig(); - case "staging": - consolex.log("using preprod server config"); - return preprodConfig; - case "prod": - consolex.log("using prod server config"); - return prodConfig; - default: - throw Error(`unsupported server configuration: ${gameEnv}`); - } -} - export interface ServerConfig { turnIntervalMs(): number; gameCreationRate(): number; diff --git a/src/core/configuration/ConfigLoader.ts b/src/core/configuration/ConfigLoader.ts new file mode 100644 index 000000000..3954e6a4c --- /dev/null +++ b/src/core/configuration/ConfigLoader.ts @@ -0,0 +1,64 @@ +import { consolex } from "../Consolex"; +import { UserSettings } from "../game/UserSettings"; +import { GameConfig } from "../Schemas"; +import { Config, GameEnv, ServerConfig } from "./Config"; +import { DefaultConfig } from "./DefaultConfig"; +import { DevConfig, DevServerConfig } from "./DevConfig"; +import { preprodConfig } from "./PreprodConfig"; +import { prodConfig } from "./ProdConfig"; + +export let cachedSC: ServerConfig = null; + +export async function getConfig( + gameConfig: GameConfig, + userSettings: UserSettings | null = null, +): Promise { + const sc = await getServerConfigFromClient(); + switch (sc.env()) { + case GameEnv.Dev: + return new DevConfig(sc, gameConfig, userSettings); + case GameEnv.Preprod: + case GameEnv.Prod: + consolex.log("using prod config"); + return new DefaultConfig(sc, gameConfig, userSettings); + default: + throw Error(`unsupported server configuration: ${process.env.GAME_ENV}`); + } +} +export async function getServerConfigFromClient(): Promise { + if (cachedSC) { + return cachedSC; + } + const response = await fetch("/api/env"); + + if (!response.ok) { + throw new Error( + `Failed to fetch server config: ${response.status} ${response.statusText}`, + ); + } + const config = await response.json(); + // Log the retrieved configuration + console.log("Server config loaded:", config); + + cachedSC = getServerConfig(config.game_env); + return cachedSC; +} +export function getServerConfigFromServer(): ServerConfig { + const gameEnv = process.env.GAME_ENV; + return getServerConfig(gameEnv); +} +export function getServerConfig(gameEnv: string) { + switch (gameEnv) { + case "dev": + consolex.log("using dev server config"); + return new DevServerConfig(); + case "staging": + consolex.log("using preprod server config"); + return preprodConfig; + case "prod": + consolex.log("using prod server config"); + return prodConfig; + default: + throw Error(`unsupported server configuration: ${gameEnv}`); + } +} diff --git a/src/server/Archive.ts b/src/server/Archive.ts index ffe90bd48..b182d2829 100644 --- a/src/server/Archive.ts +++ b/src/server/Archive.ts @@ -1,9 +1,7 @@ import { GameRecord, GameID, GameRecordSchema } from "../core/Schemas"; import { S3 } from "@aws-sdk/client-s3"; -import { - GameEnv, - getServerConfigFromServer, -} from "../core/configuration/Config"; +import { GameEnv } from "../core/configuration/Config"; +import { getServerConfigFromServer } from "../core/configuration/ConfigLoader"; import { logger } from "./Logger"; const config = getServerConfigFromServer(); diff --git a/src/server/Master.ts b/src/server/Master.ts index 53b1c70ea..2c89fe5a2 100644 --- a/src/server/Master.ts +++ b/src/server/Master.ts @@ -4,7 +4,7 @@ import express from "express"; import { GameMapType, GameType, Difficulty } from "../core/game/Game"; import { generateID } from "../core/Util"; import { PseudoRandom } from "../core/PseudoRandom"; -import { getServerConfigFromServer } from "../core/configuration/Config"; +import { getServerConfigFromServer } from "../core/configuration/ConfigLoader"; import { GameConfig, GameInfo } from "../core/Schemas"; import path from "path"; import rateLimit from "express-rate-limit"; diff --git a/src/server/MasterMetrics.ts b/src/server/MasterMetrics.ts index ebf0253f9..e598d3b26 100644 --- a/src/server/MasterMetrics.ts +++ b/src/server/MasterMetrics.ts @@ -1,7 +1,7 @@ import express from "express"; import http from "http"; import promClient from "prom-client"; -import { getServerConfigFromServer } from "../core/configuration/Config"; +import { getServerConfigFromServer } from "../core/configuration/ConfigLoader"; const config = getServerConfigFromServer(); diff --git a/src/server/Worker.ts b/src/server/Worker.ts index d476bcd1e..02fc58ad9 100644 --- a/src/server/Worker.ts +++ b/src/server/Worker.ts @@ -4,10 +4,8 @@ import { WebSocketServer } from "ws"; import path from "path"; import { fileURLToPath } from "url"; import { GameManager } from "./GameManager"; -import { - GameEnv, - getServerConfigFromServer, -} from "../core/configuration/Config"; +import { GameEnv } from "../core/configuration/Config"; +import { getServerConfigFromServer } from "../core/configuration/ConfigLoader"; import { WebSocket } from "ws"; import { Client } from "./Client"; import rateLimit from "express-rate-limit"; diff --git a/src/server/WorkerMetrics.ts b/src/server/WorkerMetrics.ts index 5b8925001..bb20e485d 100644 --- a/src/server/WorkerMetrics.ts +++ b/src/server/WorkerMetrics.ts @@ -1,6 +1,6 @@ import promClient from "prom-client"; import { GameManager } from "./GameManager"; -import { getServerConfigFromServer } from "../core/configuration/Config"; +import { getServerConfigFromServer } from "../core/configuration/ConfigLoader"; const config = getServerConfigFromServer(); const region = config.region(); diff --git a/src/server/gatekeeper b/src/server/gatekeeper index ac674b5fd..adef17d11 160000 --- a/src/server/gatekeeper +++ b/src/server/gatekeeper @@ -1 +1 @@ -Subproject commit ac674b5fd04a26e579f14070562208d51ad62d78 +Subproject commit adef17d115590c506b8b957390755f1f1b1c2beb