Page MenuHomeSealhub

notifier.ts
No OneTemporary

Authored By
Unknown
Size
2 KB
Referenced Files
None
Subscribers
None

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`);
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);
}
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;
while (true) {
// 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) {
if ((e as Error).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.info(
"🔔 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
application/javascript
Expires
Sat, Nov 7, 17:23 (2 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1181990
Default Alt Text
notifier.ts (2 KB)

Event Timeline