summary refs log tree commit diff
path: root/src/start.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/start.ts')
-rw-r--r--src/start.ts97
1 files changed, 97 insertions, 0 deletions
diff --git a/src/start.ts b/src/start.ts
new file mode 100644
index 00000000..a20581c3
--- /dev/null
+++ b/src/start.ts
@@ -0,0 +1,97 @@
+// process.env.MONGOMS_DEBUG = "true";
+import "reflect-metadata";
+import cluster, { Worker } from "cluster";
+import os from "os";
+import { red, bold, yellow, cyan } from "picocolors";
+import { initStats } from "./stats";
+import { config } from "dotenv";
+config();
+import { execSync } from "child_process";
+
+// TODO: add socket event transmission
+let cores = 1;
+try {
+	cores = Number(process.env.THREADS) || os.cpus().length;
+} catch {
+	console.log("[API] Failed to get thread count! Using 1...")
+}
+
+if (cluster.isMaster) {
+	function getCommitOrFail() {
+		try {
+			return execSync("git rev-parse HEAD").toString().trim();
+		} catch (e) {
+			return null;
+		}
+	}
+	const commit = getCommitOrFail();
+
+	console.log(
+		bold(`
+███████╗ ██████╗ ███████╗███████╗ ██████╗ ██████╗ ██████╗ ██████╗
+██╔════╝██╔═══██╗██╔════╝██╔════╝██╔════╝██╔═══██╗██╔══██╗██╔══██╗
+█████╗  ██║   ██║███████╗███████╗██║     ██║   ██║██████╔╝██║  ██║
+██╔══╝  ██║   ██║╚════██║╚════██║██║     ██║   ██║██╔══██╗██║  ██║
+██║     ╚██████╔╝███████║███████║╚██████╗╚██████╔╝██║  ██║██████╔╝
+╚═╝      ╚═════╝ ╚══════╝╚══════╝ ╚═════╝ ╚═════╝ ╚═╝  ╚═╝╚═════╝
+
+		fosscord-server | ${yellow(
+			`Pre-release (${
+				commit !== null
+					? commit.slice(0, 7)
+					: "Unknown (Git cannot be found)"
+			})`
+		)}
+
+Commit Hash: ${
+			commit !== null
+				? `${cyan(commit)} (${yellow(commit.slice(0, 7))})`
+				: "Unknown (Git cannot be found)"
+		}
+Cores: ${cyan(os.cpus().length)} (Using ${cores} thread(s).)
+`)
+	);
+
+	if (commit == null) {
+		console.log(yellow(`Warning: Git is not installed or not in PATH.`));
+	}
+
+	initStats();
+
+	console.log(`[Process] starting with ${cores} threads`);
+
+	if (cores === 1) {
+		require("./Server");
+	} else {
+		process.env.EVENT_TRANSMISSION = "process";
+
+		// Fork workers.
+		for (let i = 0; i < cores; i++) {
+			// Delay each worker start if using sqlite database to prevent locking it
+			let delay = process.env.DATABASE?.includes("://") ? 0 : i * 1000;
+			setTimeout(() => {
+				cluster.fork();
+				console.log(`[Process] worker ${cyan(i)} started.`);
+			}, delay);
+		}
+
+		cluster.on("message", (sender: Worker, message: any) => {
+			for (const id in cluster.workers) {
+				const worker = cluster.workers[id];
+				if (worker === sender || !worker) continue;
+				worker.send(message);
+			}
+		});
+
+		cluster.on("exit", (worker: any, code: any, signal: any) => {
+			console.log(
+				`[Worker] ${red(
+					`died with PID: ${worker.process.pid} , restarting ...`
+				)}`
+			);
+			cluster.fork();
+		});
+	}
+} else {
+	require("./Server");
+}