cosmostat working

This commit is contained in:
2026-03-29 09:39:43 -07:00
parent 97fdb3d5d8
commit 4c4d9e4d6f
19 changed files with 813 additions and 491 deletions

View File

@ -61,65 +61,66 @@ io.on('connection', async socket => {
/* ---------- 3. Serve static files ----------------------------------- */
/* --------------------------------------------------------------------- */
app.use(express.static('public'));
/* --- 4. Redis subscriber (patched) --------------------------------- */
const redisClient = createClient({
url: 'redis://192.168.37.1:6379',
socket: { keepAlive: 60000, // 60s TCP keep-alive
reconnectStrategy: attempts => Math.min(attempts * 100, 3000) } // back-off
});
/* --------------------------------------------------------------------- */
/* ---------- 4. Redis subscriber ------------------------------------- */
/* --------------------------------------------------------------------- */
const redisClient = createClient({ url: 'redis://192.168.37.1:6379' });
redisClient.on('error', err => console.error('Redis error', err));
(async () => {
await redisClient.connect();
const sub = redisClient.duplicate(); // duplicate to keep separate pub/sub
const sub = redisClient.duplicate();
await sub.connect();
// Subscribe to the channel that sends host stats
await sub.subscribe(
['host_metrics'],
(message, channel) => {
let payload;
try {
payload = JSON.parse(message); // message is a JSON string
} catch (e) {
console.error(`Failed to parse ${channel}`, e);
return;
}
io.emit(channel, payload);
// --------------------------------------------------------------------
// Helper that re-subscribes to a channel (and re-sends the handler)
// --------------------------------------------------------------------
async function safeSubscribe(channel, handler) {
try {
await sub.subscribe(channel, handler);
console.log(`Subscribed to ${channel}`);
} catch (e) {
console.error(`Failed to subscribe to ${channel}`, e);
}
);
}
// Subscribe to the channel that sends host stats
await sub.subscribe(
['client_summary'],
(message, channel) => {
let payload;
try {
payload = JSON.parse(message); // message is a JSON string
} catch (e) {
console.error(`Failed to parse ${channel}`, e);
return;
}
// ---------------------------------------------------------------
// Subscribe to all required channels
// ---------------------------------------------------------------
await safeSubscribe('host_metrics', (msg) => forward('host_metrics', msg));
await safeSubscribe('client_summary', (msg) => forward('client_summary', msg));
// ---------------------------------------------------------------
// Forward messages to Socket.io
// ---------------------------------------------------------------
function forward(channel, message) {
try {
const payload = JSON.parse(message);
io.emit(channel, payload);
} catch (e) {
console.error(`Failed to parse message from ${channel}`, e);
}
);
}
// Subscribe to the channel that sends host stats
await sub.subscribe(
['client_hostnames'],
(message, channel) => {
let payload;
try {
payload = JSON.parse(message); // message is a JSON string
} catch (e) {
console.error(`Failed to parse ${channel}`, e);
return;
}
io.emit(channel, payload);
}
);
// ----------------------------------------------------------------
// Re-subscribe automatically when the Redis connection reconnects
// ----------------------------------------------------------------
sub.on('reconnecting', () => console.log('Redis reconnecting…'));
sub.on('ready', async () => {
console.log('Redis ready - re-subscribing to all channels');
await safeSubscribe('host_metrics', (msg) => forward('host_metrics', msg));
await safeSubscribe('client_summary', (msg) => forward('client_summary', msg));
});
sub.on('error', err => console.error('Subscriber error', err));
// Optional: if the connection ends for any reason, close the process
sub.on('end', () => {
console.error('Redis connection closed - exiting');
process.exit(1);
});
})();
/* --------------------------------------------------------------------- */