mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-29 14:45:24 +00:00
Formalises three ad-hoc publish paths that already existed: automation-events.ts, metrics/automation-bridge.ts and the hostSessionStatus singleton, now the host.session.status topic. Both invariants the old code relied on are preserved. Publishing stays fire-and-forget, so a failing subscriber cannot disturb a metrics poll or a host delete. The automations engine subscribes to the bus at scheduler start instead of being imported ad hoc, which keeps the edge one-directional: automations may import repositories, hosts modules must not import automations.
52 lines
1.4 KiB
TypeScript
52 lines
1.4 KiB
TypeScript
import { pluginEvents, TOPICS } from "../plugins/events.js";
|
|
|
|
type HostSessionStatusListener = (hostId: number, online: boolean) => void;
|
|
|
|
export interface HostSessionStatusPayload {
|
|
hostId: number;
|
|
online: boolean;
|
|
}
|
|
|
|
export class HostSessionStatus {
|
|
private counts = new Map<number, number>();
|
|
private listeners = new Set<HostSessionStatusListener>();
|
|
|
|
register(hostId: number): () => void {
|
|
const count = this.counts.get(hostId) ?? 0;
|
|
this.counts.set(hostId, count + 1);
|
|
if (count === 0) this.emit(hostId, true);
|
|
|
|
let active = true;
|
|
return () => {
|
|
if (!active) return;
|
|
active = false;
|
|
|
|
const next = (this.counts.get(hostId) ?? 1) - 1;
|
|
if (next > 0) {
|
|
this.counts.set(hostId, next);
|
|
return;
|
|
}
|
|
|
|
this.counts.delete(hostId);
|
|
this.emit(hostId, false);
|
|
};
|
|
}
|
|
|
|
subscribe(listener: HostSessionStatusListener): () => void {
|
|
this.listeners.add(listener);
|
|
return () => this.listeners.delete(listener);
|
|
}
|
|
|
|
private emit(hostId: number, online: boolean): void {
|
|
for (const listener of this.listeners) listener(hostId, online);
|
|
// Also published as a topic so plugins (and anything else on the bus) can
|
|
// observe session status without holding a reference to this singleton.
|
|
pluginEvents.emit(TOPICS.hostSessionStatus, {
|
|
hostId,
|
|
online,
|
|
} satisfies HostSessionStatusPayload);
|
|
}
|
|
}
|
|
|
|
export const hostSessionStatus = new HostSessionStatus();
|