This commit is contained in:
Rizky 2024-01-25 13:32:34 +07:00
parent 5e8a44765b
commit 6959145d00
6 changed files with 91 additions and 26 deletions

3
.gitignore vendored
View File

@ -178,4 +178,5 @@ app/web
app/srv
app/db
app/static
.data
.data
.pm_port

BIN
bun.lockb

Binary file not shown.

BIN
dockerzip

Binary file not shown.

View File

@ -4,7 +4,7 @@
"type": "module",
"scripts": {
"dev": "bun run --silent --watch ./pkgs/index.ts dev",
"prod": "bun run --silent ./pkgs/index.ts",
"prod": "bun run --silent ./pkgs/prod.ts",
"pkgs-upgrade": "bun run --silent ./pkgs/upgrade.ts"
},
"workspaces": [
@ -18,6 +18,7 @@
"typescript": "^5.0.0"
},
"dependencies": {
"exit-hook": "^4.0.0",
"firebase-admin": "^11.11.0"
}
}

63
pkgs/prod.ts Normal file
View File

@ -0,0 +1,63 @@
import { Subprocess } from "bun";
import exitHook from "exit-hook";
import { checkPort, randomBetween } from "utils/ensure";
let port = 0;
try {
port = parseInt(await Bun.file(".pm_port").text());
} catch (e) {
while (true) {
port = randomBetween(5000, 15000);
if (await checkPort(port)) {
Bun.write(".pm_port", port.toString());
break;
}
}
}
exitHook((signal) => {
if (main.process && !main.process.killed) {
main.process.kill();
}
console.log(`Exiting with signal: ${signal}`);
});
const main = {
process: null as null | Subprocess,
restart: {
timeout: null as any,
},
};
console.log("Process Manager running at port:", port);
const startMain = () => {
let mode = "started";
if (main.process && !main.process.killed) return;
if (main.process && main.process.killed) mode = "restarted";
main.process = Bun.spawn({
cmd: ["bun", "run", "pkgs/index.ts"],
cwd: process.cwd(),
stdout: "inherit",
stderr: "inherit",
onExit(subprocess, exitCode, signalCode, error) {
clearTimeout(main.restart.timeout);
main.restart.timeout = setTimeout(startMain, 500);
},
});
console.log(`Main process`, mode, "pid:", main.process.pid);
};
startMain();
Bun.serve({
port,
async fetch(request, server) {
if (main.process && !main.process.killed) {
main.process.kill();
await main.process.exited;
}
return new Response("OK");
},
});

View File

@ -3,32 +3,10 @@ import { g } from "./global";
export const ensureNotRunning = async () => {
await new Promise<void>(async (resolve) => {
const checkPort = () => {
return new Promise<boolean>(async (done) => {
try {
const s = await connect({
hostname: "0.0.0.0",
port: g.port,
socket: {
open(socket) {},
data(socket, data) {},
close(socket) {},
drain(socket) {},
error(socket, error) {},
},
});
s.end();
done(false);
} catch (e) {
done(true);
}
});
};
if (!(await checkPort())) {
if (!(await checkPort(g.port))) {
g.log.warn(`Port ${g.port} is used, waiting...`);
setInterval(async () => {
if (await checkPort()) resolve();
if (await checkPort(g.port)) resolve();
}, 500);
} else {
resolve();
@ -39,3 +17,25 @@ export const ensureNotRunning = async () => {
export function randomBetween(min: number, max: number) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
export const checkPort = (port: number) => {
return new Promise<boolean>(async (done) => {
try {
const s = await connect({
hostname: "0.0.0.0",
port,
socket: {
open(socket) {},
data(socket, data) {},
close(socket) {},
drain(socket) {},
error(socket, error) {},
},
});
s.end();
done(false);
} catch (e) {
done(true);
}
});
};