Page MenuHomeSealhub

notifier.ts
No OneTemporary

notifier.ts

import { WebSocketServer, WebSocket } from "ws";
const APP_DOWN_ERROR_MESSAGE = "App is currently down";
export const APP_BACK_ALIVE_SIGNAL = "app-back-alive";
const sleep = (time: number) =>
new Promise((resolve) => {
setTimeout(resolve, time);
});
async function get_status(
app_port: number
): Promise<{ started_at: number; status: string }> {
const r = await fetch(`http://127.0.0.1:${app_port}/status.json`);
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
return (await r.json()) as { started_at: number; status: string };
}
async function wait_for_run_id_to_change(app_port: number) {
let first_timestamp: number;
try {
const { started_at } = await get_status(app_port);
first_timestamp = started_at;
} catch (e) {
await wait_for_app_to_be_stable(app_port);
return;
}
if (!first_timestamp) {
throw new Error(APP_DOWN_ERROR_MESSAGE);
}
// eslint-disable-next-line no-constant-condition
while (true) {
// eslint-disable-next-line no-await-in-loop
const { started_at } = await get_status(app_port).catch(() => ({
started_at: first_timestamp,
}));
if (started_at !== first_timestamp) {
return;
}
// eslint-disable-next-line no-await-in-loop
await sleep(100);
}
}
async function wait_for_app_to_be_stable(app_port: number, n = 3) {
// eslint-disable-next-line no-console
console.log("Waiting for app to be stable....");
let counter = 0;
// eslint-disable-next-line no-constant-condition
while (true) {
console.debug("notifier.ts:53");
// eslint-disable-next-line no-await-in-loop
const { status } = await get_status(app_port).catch(() => ({
status: "down",
}));
if (status == "running") {
// eslint-disable-next-line no-console
console.log(counter);
counter++;
} else {
counter = 0;
}
if (counter == n) {
return;
}
// eslint-disable-next-line no-await-in-loop
await sleep(100);
}
}
let restart_promise: Promise<void> | null = null;
async function wait_for_app_restart(app_port: number) {
if (restart_promise) {
return restart_promise;
}
try {
restart_promise = wait_for_run_id_to_change(app_port);
await restart_promise;
} catch (e) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
if (e.message !== APP_DOWN_ERROR_MESSAGE) {
throw e;
}
}
restart_promise = null;
await wait_for_app_to_be_stable(app_port);
}
export function make_notifier(port: number, app_port: number) {
const server = new WebSocketServer({
port,
});
let sockets: WebSocket[] = [];
server.on("connection", function (socket) {
sockets.push(socket);
// When a socket closes, or disconnects, remove it from the array.
socket.on("close", function () {
sockets = sockets.filter((s) => s !== socket);
});
});
console.log(
"build notifier listening on websocket at port " + port.toString()
);
return function notify(message: string) {
sockets.forEach((s) => s.send(message));
void wait_for_app_restart(app_port).then(() => {
sockets.forEach((s) => s.send(APP_BACK_ALIVE_SIGNAL));
});
};
}

File Metadata

Mime Type
text/x-java
Expires
Mon, Jul 21, 00:24 (1 d, 22 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
627433
Default Alt Text
notifier.ts (2 KB)

Event Timeline