diff --git a/server/api/AdminAPI.js b/server/api/AdminAPI.js index ee4e603..f5da885 100644 --- a/server/api/AdminAPI.js +++ b/server/api/AdminAPI.js @@ -2,8 +2,8 @@ const express = require('express'); const router = express.Router(); const debugMode = Array.from(process.argv.map((arg) => arg.trim().toLowerCase())).includes('debug'); const logger = require('../modules/Logger')(debugMode); -const socketManager = new (require('../modules/SocketManager.js'))().getInstance(); -const gameManager = new (require('../modules/GameManager.js'))().getInstance(); +const socketManager = (require('../modules/SocketManager.js')).instance; +const gameManager = (require('../modules/GameManager.js')).instance; const globals = require('../config/globals.js'); const cors = require('cors'); diff --git a/server/api/GamesAPI.js b/server/api/GamesAPI.js index 5a800fd..984cbbc 100644 --- a/server/api/GamesAPI.js +++ b/server/api/GamesAPI.js @@ -7,7 +7,7 @@ const rateLimit = require('express-rate-limit').default; const globals = require('../config/globals.js'); const cors = require('cors'); -const gameManager = new GameManager().getInstance(); +const gameManager = GameManager.instance; const gameCreationLimit = process.env.NODE_ENV.trim() === 'production' ? 20 diff --git a/server/modules/ActiveGameRunner.js b/server/modules/ActiveGameRunner.js index 0a2a533..1749bee 100644 --- a/server/modules/ActiveGameRunner.js +++ b/server/modules/ActiveGameRunner.js @@ -4,9 +4,14 @@ const globals = require('../config/globals'); class ActiveGameRunner { constructor (logger) { + if (ActiveGameRunner.instance) { + throw new Error('The server tried to instantiate more than one ActiveGameRunner'); + } + logger.info('CREATING SINGLETON ACTIVE GAME RUNNER'); this.activeGames = new Map(); this.timerThreads = {}; this.logger = logger; + ActiveGameRunner.instance = this; } /* We're only going to fork a child process for games with a timer. They will report back to the parent process whenever @@ -61,17 +66,4 @@ class ActiveGameRunner { }; } -class Singleton { - constructor (logger) { - if (!Singleton.instance) { - logger.info('CREATING SINGLETON ACTIVE GAME RUNNER'); - Singleton.instance = new ActiveGameRunner(logger); - } - } - - getInstance () { - return Singleton.instance; - } -} - -module.exports = Singleton; +module.exports = ActiveGameRunner; diff --git a/server/modules/GameManager.js b/server/modules/GameManager.js index 8a2b6aa..9df27d7 100644 --- a/server/modules/GameManager.js +++ b/server/modules/GameManager.js @@ -6,11 +6,16 @@ const GameStateCurator = require('./GameStateCurator'); const UsernameGenerator = require('./UsernameGenerator'); class GameManager { - constructor (logger, environment) { + constructor (logger, environment, activeGameRunner) { + if (GameManager.instance) { + throw new Error('The server tried to instantiate more than one GameManager'); + } + logger.info('CREATING SINGLETON GAME MANAGER'); this.logger = logger; this.environment = environment; - this.activeGameRunner = new ActiveGameRunner(logger).getInstance(); + this.activeGameRunner = activeGameRunner; this.namespace = null; + GameManager.instance = this; } setGameSocketNamespace = (namespace) => { @@ -501,17 +506,4 @@ function getGameSize (cards) { return quantity; } -class Singleton { - constructor (logger, environment) { - if (!Singleton.instance) { - logger.info('CREATING SINGLETON GAME MANAGER'); - Singleton.instance = new GameManager(logger, environment); - } - } - - getInstance () { - return Singleton.instance; - } -} - -module.exports = Singleton; +module.exports = GameManager; diff --git a/server/modules/ServerBootstrapper.js b/server/modules/ServerBootstrapper.js index fa111c5..aed2cf4 100644 --- a/server/modules/ServerBootstrapper.js +++ b/server/modules/ServerBootstrapper.js @@ -6,6 +6,7 @@ const fs = require('fs'); const crypto = require('crypto'); const SocketManager = require('./SocketManager.js'); const GameManager = require('./GameManager.js'); +const ActiveGameRunner = require("./ActiveGameRunner.js"); const { ENVIRONMENT } = require('../config/globals.js'); const rateLimit = require('express-rate-limit').default; @@ -13,10 +14,11 @@ const ServerBootstrapper = { singletons: (logger) => { return { - socketManager: new SocketManager(logger).getInstance(), + activeGameRunner: new ActiveGameRunner(logger), + socketManager: new SocketManager(logger, ActiveGameRunner.instance), gameManager: process.env.NODE_ENV.trim() === 'development' - ? new GameManager(logger, ENVIRONMENT.LOCAL).getInstance() - : new GameManager(logger, ENVIRONMENT.PRODUCTION).getInstance() + ? new GameManager(logger, ENVIRONMENT.LOCAL, ActiveGameRunner.instance) + : new GameManager(logger, ENVIRONMENT.PRODUCTION, ActiveGameRunner.instance) }; }, diff --git a/server/modules/SocketManager.js b/server/modules/SocketManager.js index 428aa77..bd2ed04 100644 --- a/server/modules/SocketManager.js +++ b/server/modules/SocketManager.js @@ -3,9 +3,15 @@ const EVENT_IDS = globals.EVENT_IDS; const { RateLimiterMemory } = require('rate-limiter-flexible'); class SocketManager { - constructor (logger) { + constructor (logger, activeGameRunner) { + if (SocketManager.instance) { + throw new Error('The server attempted to instantiate more than one SocketManager.'); + } + logger.info('CREATING SINGLETON SOCKET MANAGER'); this.logger = logger; this.io = null; + this.activeGameRunner = activeGameRunner; + SocketManager.instance = this; } broadcast = (message) => { @@ -122,17 +128,4 @@ function registerRateLimiter (server, logger) { }); } -class Singleton { - constructor (logger) { - if (!Singleton.instance) { - logger.info('CREATING SINGLETON SOCKET MANAGER'); - Singleton.instance = new SocketManager(logger); - } - } - - getInstance () { - return Singleton.instance; - } -} - -module.exports = Singleton; +module.exports = SocketManager; diff --git a/spec/unit/server/modules/GameManager_Spec.js b/spec/unit/server/modules/GameManager_Spec.js index ac6d265..4811ccb 100644 --- a/spec/unit/server/modules/GameManager_Spec.js +++ b/spec/unit/server/modules/GameManager_Spec.js @@ -5,7 +5,8 @@ const USER_TYPES = globals.USER_TYPES; const STATUS = globals.STATUS; const Person = require('../../../../server/model/Person'); const GameManager = require('../../../../server/modules/GameManager.js'); -const GameStateCurator = require('../../../../server/modules/GameStateCurator'); +const GameStateCurator = require('../../../../server/modules/GameStateCurator.js'); +const ActiveGameRunner = require("../../../../server/modules/ActiveGameRunner.js"); const logger = require('../../../../server/modules/Logger.js')(false); describe('GameManager', () => { @@ -18,7 +19,7 @@ describe('GameManager', () => { const inObj = { emit: () => {} }; namespace = { in: () => { return inObj; }, to: () => { return inObj; } }; socket = { id: '123', emit: () => {}, to: () => { return { emit: () => {} }; } }; - gameManager = new GameManager(logger, globals.ENVIRONMENT.PRODUCTION).getInstance(); + gameManager = new GameManager(logger, globals.ENVIRONMENT.PRODUCTION, new ActiveGameRunner(logger)); gameManager.setGameSocketNamespace(namespace); });