Files
psu-schedule/server/watch.js

44 lines
1.6 KiB
JavaScript

import { getCatalog, catalogFailure } from "./source.js";
import { syncIndex } from "./directory.js";
import { checkCatalog, checkSource } from "./alerts.js";
// The server checks the university's catalog by itself, not only when a request asks: a
// republished document is parsed within minutes, the clients' next refresh gets it, and the
// owner hears about problems (see alerts.js). An unchanged catalog costs two listings.
const INTERVAL = Number(process.env.PSU_WATCH_INTERVAL_MS) || 5 * 60 * 1000;
/** For /api/health. */
export const watchStatus = { intervalMinutes: INTERVAL / 60000, lastAt: null, lastError: null };
let running = null;
/** One check: the catalog (refreshed), the index of a changed catalog, the messages. */
export function watchOnce() {
// A slow university must not stack checks on top of each other.
running ||= check().finally(() => {
running = null;
});
return running;
}
async function check() {
try {
const catalog = await getCatalog(true);
// A failed crawl answers with the saved catalog: nothing new to read or report then.
if (!catalog.stale) await checkCatalog(await syncIndex(catalog), catalog);
watchStatus.lastError = catalog.stale ? catalog.error || null : null;
} catch (error) {
watchStatus.lastError = error.message;
}
await checkSource(catalogFailure());
watchStatus.lastAt = new Date().toISOString();
}
let timer = null;
/** Checks every few minutes (PSU_WATCH_INTERVAL_MS) for as long as the process runs. */
export function startWatch() {
if (timer) return;
timer = setInterval(watchOnce, INTERVAL);
timer.unref();
}