diff --git a/README.md b/README.md index 1f4b5293b..51d71f891 100644 --- a/README.md +++ b/README.md @@ -35,8 +35,8 @@ - Get a terminal into the running container: `docker exec -it odota-core bash` - The process manager `pm2` is used to manage the individual services. Each is run as a separate Node.js process. - `pm2 list` See the currently running services. - - `pm2 start manifest.json` Start all the services according to the manifest file - - `pm2 start manifest.json --only web` Starts a specific service + - `pm2 start ecosystem.config.js` Start all the services + - `pm2 start ecosystem.config.js --only web` Starts a specific service - `pm2 stop web` Stop a specific service - `pm2 stop all` Stop all the services - `pm2 logs web` Inspect the output of a service diff --git a/docker/main-launch.sh b/docker/main-launch.sh index 7918d87ac..533bfb22c 100755 --- a/docker/main-launch.sh +++ b/docker/main-launch.sh @@ -7,7 +7,7 @@ # Rebuild to replace mapped directory build npm run build -pm2 start manifest.json --only web +pm2 start ecosystem.config.js --only web # We shall now display logs indefinitely pm2 logs diff --git a/ecosystem.config.js b/ecosystem.config.js new file mode 100644 index 000000000..63001fc7a --- /dev/null +++ b/ecosystem.config.js @@ -0,0 +1,157 @@ +const { GROUP, NODE_ENV } = require('./config.js'); + +let arr = [ + { + "name": "web", + "script": "svc/web.mjs", + "group": "web", + }, + { + "name": "retriever", + "script": "svc/retriever.mjs", + "group": "retriever", + }, + { + "name": "proxy", + "script": "svc/proxy.mjs", + "group": "proxy", + }, + { + "name": "parser", + "script": "svc/parser.mjs", + }, + { + "name": "apiadmin", + "script": "svc/apiadmin.mjs", + "group": "backend", + }, + { + "name": "mmr", + "script": "svc/mmr.mjs", + "group": "backend", + }, + { + "name": "profiler", + "script": "svc/profiler.mjs", + "group": "backend", + }, + { + "name": "scanner", + "script": "svc/scanner.mjs", + "group": "backend", + }, + { + "name": "fullhistory", + "script": "svc/fullhistory.mjs", + "group": "backend", + }, + { + "name": "fullhistory", + "script": "svc/autofullhistory.mjs", + "group": "backend", + }, + { + "name": "monitor", + "script": "svc/monitor.mjs", + "group": "backend", + }, + { + "name": "gcdata", + "script": "svc/gcdata.mjs", + "group": "backend", + }, + { + "name": "buildsets", + "script": "svc/buildsets.mjs", + "group": "backend", + }, + { + "name": "cosmetics", + "script": "svc/cosmetics.mjs", + "group": "backend", + }, + { + "name": "distributions", + "script": "svc/distributions.mjs", + "group": "backend", + }, + { + "name": "heroes", + "script": "svc/heroes.mjs", + "group": "backend", + }, + { + "name": "herostats", + "script": "svc/herostats.mjs", + "group": "backend", + }, + { + "name": "items", + "script": "svc/items.mjs", + "group": "backend", + }, + { + "name": "leagues", + "script": "svc/leagues.mjs", + "group": "backend", + }, + { + "name": "livegames", + "script": "svc/livegames.mjs", + "group": "backend", + }, + { + "name": "proplayers", + "script": "svc/proplayers.mjs", + "group": "backend", + }, + { + "name": "teams", + "script": "svc/teams.mjs", + "group": "backend", + }, + { + "name": "scenarios", + "script": "svc/scenarios.mjs", + "group": "backend", + }, + { + "name": "scenariosCleanup", + "script": "svc/scenariosCleanup.mjs", + "group": "backend", + }, + { + "name": "counts", + "script": "svc/counts.mjs", + "group": "backend", + }, + { + "name": "syncSubs", + "script": "svc/syncSubs.mjs", + "group": "backend", + }, + { + "name": "cassandraDelete", + "script": "svc/cassandraDelete.mjs", + "group": "backend", + } + ]; + +// If GROUP is set filter to only the matching group +arr = arr.filter(app => !GROUP || app.group === GROUP); + +const apps = arr.map(app => { + const dev = NODE_ENV === 'development'; + return { + ...app, + watch: dev ? true : false, + ignore_watch: [".git", "node_modules"], + exec_mode: 'fork', + instances: 1, + } +}); + +module.exports = { + apps +}; + \ No newline at end of file diff --git a/index.js b/index.js deleted file mode 100644 index aaaffe9b4..000000000 --- a/index.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Entry point for the application. - * */ -const cp = require('child_process'); -const pm2 = require('pm2'); -const { apps } = require('./manifest.json'); - -const args = process.argv.slice(2); -const group = args[0] || process.env.GROUP; - -if (process.env.PROVIDER === 'gce') { - cp.execSync( - 'curl -H "Metadata-Flavor: Google" -L http://metadata.google.internal/computeMetadata/v1/project/attributes/env > /usr/src/.env' - ); -} -if (process.env.ROLE) { - // if role variable is set just run that script - const app = apps.find((app) => app.group === process.env.ROLE); - import('./' + app?.script); -} else if (group) { - pm2.connect(() => { - apps - .filter((app) => group === app.group) - .forEach((app) => { - pm2.start( - app.script, - { - instances: app.instances, - restartDelay: 10000, - }, - (err) => { - if (err) { - console.error(err); - } - } - ); - }); - }); - // pm2.disconnect(); - // Clean up the logs once an hour - setInterval(() => pm2.flush(), 3600 * 1000); -} else { - // Block indefinitely (keep process alive for Docker) - process.stdin.resume(); -} diff --git a/index.mjs b/index.mjs new file mode 100644 index 000000000..192b889a9 --- /dev/null +++ b/index.mjs @@ -0,0 +1,27 @@ +/** + * Entry point for the application. + * */ +import cp from 'child_process'; +if (process.env.PROVIDER === 'gce') { + cp.execSync( + 'curl -H "Metadata-Flavor: Google" -L http://metadata.google.internal/computeMetadata/v1/project/attributes/env > /usr/src/.env' + ); +} +// Do this after the metadata download since it uses config +const ecosystem = await import('./ecosystem.config.js'); +if (process.env.ROLE) { + // if role variable is set just run that script + const app = ecosystem.apps.find((app) => app.name === process.env.ROLE); + import('./' + app.script); +} else if (process.env.GROUP) { + // or run the group with pm2 + cp.execSync( + 'pm2 start ecosystem.config.js' + ); + setInterval(() => { + cp.execSync('pm2 flush all'); + }, 60 * 60 * 1000); +} else { + // Block indefinitely (keep process alive for Docker) + process.stdin.resume(); +} diff --git a/manifest.json b/manifest.json deleted file mode 100755 index 397297e35..000000000 --- a/manifest.json +++ /dev/null @@ -1,228 +0,0 @@ -{ - "apps": [ - { - "script": "svc/apiadmin.mjs", - "watch": true, - "ignore_watch": [".git", "node_modules"], - "group": "backend", - "exec_mode": "cluster", - "instances": 1 - }, - { - "script": "svc/mmr.mjs", - "watch": true, - "ignore_watch": [".git", "node_modules"], - "group": "backend", - "exec_mode": "cluster", - "instances": 1 - }, - { - "script": "svc/profiler.mjs", - "watch": true, - "ignore_watch": [".git", "node_modules"], - "group": "backend", - "exec_mode": "cluster", - "instances": 1 - }, - { - "script": "svc/scanner.mjs", - "watch": true, - "ignore_watch": [".git", "node_modules"], - "group": "backend", - "exec_mode": "cluster", - "instances": 1 - }, - { - "script": "svc/fullhistory.mjs", - "watch": true, - "ignore_watch": [".git", "node_modules"], - "group": "backend", - "exec_mode": "cluster", - "instances": 1 - }, - { - "script": "svc/autofullhistory.mjs", - "watch": true, - "ignore_watch": [".git", "node_modules"], - "group": "backend", - "exec_mode": "cluster", - "instances": 1 - }, - { - "script": "svc/monitor.mjs", - "watch": true, - "ignore_watch": [".git", "node_modules"], - "group": "backend", - "exec_mode": "cluster", - "instances": 1 - }, - { - "script": "svc/backupscanner.mjs", - "watch": true, - "ignore_watch": [".git", "node_modules"], - "group": "disabled", - "exec_mode": "cluster", - "instances": 1 - }, - { - "script": "svc/gcdata.mjs", - "watch": true, - "ignore_watch": [".git", "node_modules"], - "group": "backend", - "exec_mode": "cluster", - "instances": 1 - }, - { - "script": "svc/buildsets.mjs", - "watch": true, - "ignore_watch": [".git", "node_modules"], - "group": "backend", - "exec_mode": "cluster", - "instances": 1 - }, - { - "script": "svc/cosmetics.mjs", - "watch": true, - "ignore_watch": [".git", "node_modules"], - "group": "backend", - "exec_mode": "cluster", - "instances": 1 - }, - { - "script": "svc/distributions.mjs", - "watch": true, - "ignore_watch": [".git", "node_modules"], - "group": "backend", - "exec_mode": "cluster", - "instances": 1 - }, - { - "script": "svc/heroes.mjs", - "watch": true, - "ignore_watch": [".git", "node_modules"], - "group": "backend", - "exec_mode": "cluster", - "instances": 1 - }, - { - "script": "svc/herostats.mjs", - "watch": true, - "ignore_watch": [".git", "node_modules"], - "group": "backend", - "exec_mode": "cluster", - "instances": 1 - }, - { - "script": "svc/items.mjs", - "watch": true, - "ignore_watch": [".git", "node_modules"], - "group": "backend", - "exec_mode": "cluster", - "instances": 1 - }, - { - "script": "svc/leagues.mjs", - "watch": true, - "ignore_watch": [".git", "node_modules"], - "group": "backend", - "exec_mode": "cluster", - "instances": 1 - }, - { - "script": "svc/livegames.mjs", - "watch": true, - "ignore_watch": [".git", "node_modules"], - "group": "backend", - "exec_mode": "cluster", - "instances": 1 - }, - { - "script": "svc/proplayers.mjs", - "watch": true, - "ignore_watch": [".git", "node_modules"], - "group": "backend", - "exec_mode": "cluster", - "instances": 1 - }, - { - "script": "svc/teams.mjs", - "watch": true, - "ignore_watch": [".git", "node_modules"], - "group": "backend", - "exec_mode": "cluster", - "instances": 1 - }, - { - "script": "svc/web.mjs", - "watch": true, - "ignore_watch": [".git", "node_modules"], - "group": "web", - "exec_mode": "cluster", - "instances": 1 - }, - { - "script": "svc/retriever.mjs", - "watch": true, - "ignore_watch": [".git", "node_modules"], - "group": "retriever", - "exec_mode": "cluster", - "instances": 1 - }, - { - "script": "svc/proxy.mjs", - "watch": true, - "ignore_watch": [".git", "node_modules"], - "group": "proxy", - "exec_mode": "cluster", - "instances": 1 - }, - { - "script": "svc/parser.mjs", - "watch": true, - "ignore_watch": [".git", "node_modules"], - "group": "parser", - "exec_mode": "cluster", - "instances": 1 - }, - { - "script": "svc/scenarios.mjs", - "watch": true, - "ignore_watch": [".git", "node_modules"], - "group": "backend", - "exec_mode": "cluster", - "instances": 1 - }, - { - "script": "svc/scenariosCleanup.mjs", - "watch": true, - "ignore_watch": [".git", "node_modules"], - "group": "backend", - "exec_mode": "cluster", - "instances": 1 - }, - { - "script": "svc/counts.mjs", - "watch": true, - "ignore_watch": [".git", "node_modules"], - "group": "backend", - "exec_mode": "cluster", - "instances": 1 - }, - { - "script": "svc/syncSubs.mjs", - "watch": true, - "ignore_watch": [".git", "node_modules"], - "group": "backend", - "exec_mode": "cluster", - "instances": 1 - }, - { - "script": "svc/cassandraDelete.mjs", - "watch": true, - "ignore_watch": [".git", "node_modules"], - "group": "backend", - "exec_mode": "cluster", - "instances": 1 - } - ] -} diff --git a/package.json b/package.json index e9873514d..373244e57 100644 --- a/package.json +++ b/package.json @@ -3,9 +3,8 @@ "description": "Open source Dota data platform", "version": "22.0.0", "license": "MIT", - "main": "index.js", "scripts": { - "start": "node index", + "start": "node index.mjs", "test": "NODE_ENV=test mocha --exit", "build": "npm install && npm run typecheck", "tsc": "tsc --project tsconfig.json", diff --git a/tsconfig.json b/tsconfig.json index 0b40ead72..eb6512637 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,11 +1,10 @@ { "compilerOptions": { "target": "es2020", - "lib": ["es2020"], + "module": "NodeNext", "allowJs": true, "strict": true, "esModuleInterop": true, - "module": "NodeNext", "outDir": "./build", "resolveJsonModule": true, "skipLibCheck": true