Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 19 additions & 7 deletions apps/hub/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ if (import.meta.main) {
const log = getLogger(["corbits-builder", "hub"]);
let close = async () => {};
let stopping: Promise<void> | undefined;
let stopRequested = false;
let startupDone = false;
const shutDown = async () => {
for (const step of [close, dispose]) {
try {
Expand All @@ -28,6 +30,7 @@ if (import.meta.main) {
const exitOnFatal = (message: string) => async (error: unknown) => {
try {
log.error(message, errorMetadata(error));
// Unlike a signal, this does not wait for startup: a startup stuck on the failure would keep the hub up instead of letting its supervisor restart it.
await stop();
} finally {
// Handles a failed shutdown left open would keep a broken hub alive instead of letting its supervisor restart it.
Expand All @@ -39,14 +42,18 @@ if (import.meta.main) {
exitOnFatal("Hub hit an unhandled rejection"),
);
process.on("uncaughtException", exitOnFatal("Hub hit an uncaught exception"));
process.once("SIGTERM", () => {
void stop();
});
process.once("SIGINT", () => {
void stop();
});
try {
// Startup takes seconds; a stop meanwhile is recorded and acted on when startup finishes, so it closes what startup opened.
const requestStop = () => {
stopRequested = true;
if (startupDone) void stop();
};
process.once("SIGTERM", requestStop);
process.once("SIGINT", requestStop);
const start = async () => {
const runtime = await createHubRuntime();
close = () => runtime.close();
// A stop requested meanwhile must not open the port; the stop after startup closes the runtime.
if (stopRequested) return;
const server = Bun.serve({
hostname: runtime.hostname,
port: runtime.port,
Expand All @@ -63,6 +70,9 @@ if (import.meta.main) {
log.info(
"Hub ready: Postgres connected; local Interchange sidecar provisioner",
);
};
try {
await start();
} catch (error) {
log.error(
"Hub startup failed; check environment and database readiness",
Expand All @@ -71,4 +81,6 @@ if (import.meta.main) {
process.exitCode = 1;
await stop();
}
startupDone = true;
if (stopRequested) await stop();
}