Publishing to cluster/workers
This commit is contained in:
parent
e1ffcaa696
commit
3b9ad5d7a7
|
|
@ -320,7 +320,6 @@ function startSDLStatusPub() {
|
||||||
? sdlCfg.update_interval.cluster_status
|
? sdlCfg.update_interval.cluster_status
|
||||||
: 10000;
|
: 10000;
|
||||||
|
|
||||||
// config.modules.mqtt.topics.sdl-mgr.pub.sdl_cluster-status
|
|
||||||
const statusTopic = mqttCfg.topics?.[module]?.pub?.['sdl_cluster-status'];
|
const statusTopic = mqttCfg.topics?.[module]?.pub?.['sdl_cluster-status'];
|
||||||
if (!statusTopic) {
|
if (!statusTopic) {
|
||||||
log(`${module}: ${statusTopic} not configured`);
|
log(`${module}: ${statusTopic} not configured`);
|
||||||
|
|
@ -344,6 +343,12 @@ function startSDLStatusPub() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function publishStatus(client, topic) {
|
function publishStatus(client, topic) {
|
||||||
|
// Load current cluster state
|
||||||
|
const clusterState = loadClusterState(config);
|
||||||
|
|
||||||
|
// Recompute stats to get latest resource totals
|
||||||
|
const updatedState = computeStats(clusterState);
|
||||||
|
|
||||||
//get ip addr
|
//get ip addr
|
||||||
const interfaces = os.networkInterfaces();
|
const interfaces = os.networkInterfaces();
|
||||||
let ip_addr = null;
|
let ip_addr = null;
|
||||||
|
|
@ -383,6 +388,8 @@ function publishStatus(client, topic) {
|
||||||
update_cmd: `curl -s http://${ip_addr}:${config.modules.web.port}/dist/install-sdl-wkr.sh | bash -s ${ip_addr}`
|
update_cmd: `curl -s http://${ip_addr}:${config.modules.web.port}/dist/install-sdl-wkr.sh | bash -s ${ip_addr}`
|
||||||
},
|
},
|
||||||
cluster: config.cluster,
|
cluster: config.cluster,
|
||||||
|
resources: updatedState.meta.stats.resources, // ✅ Add cluster resources
|
||||||
|
workers: updatedState.meta.stats.workers, // ✅ Add worker counts
|
||||||
modules: Object.fromEntries(
|
modules: Object.fromEntries(
|
||||||
Object.entries(config.modules).map(([name, mod]) => [
|
Object.entries(config.modules).map(([name, mod]) => [
|
||||||
name,
|
name,
|
||||||
|
|
@ -407,6 +414,78 @@ function publishStatus(client, topic) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ✅ NEW: Publish individual worker details
|
||||||
|
function startWorkersPub() {
|
||||||
|
const sdlCfg = config.modules[module];
|
||||||
|
const mqttCfg = config.modules.mqtt;
|
||||||
|
|
||||||
|
if (!sdlCfg?.enabled) {
|
||||||
|
log(`${module}: disabled, not publishing workers`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mqttCfg?.enabled) {
|
||||||
|
log(`${module}: MQTT disabled, cannot publish workers`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const workersInterval =
|
||||||
|
Number.isInteger(sdlCfg.update_interval.cluster_workers) &&
|
||||||
|
sdlCfg.update_interval.cluster_workers > 0
|
||||||
|
? sdlCfg.update_interval.cluster_workers
|
||||||
|
: 10000;
|
||||||
|
|
||||||
|
const workersTopic = mqttCfg.topics?.[module]?.pub?.['sdl_cluster-workers'];
|
||||||
|
if (!workersTopic) {
|
||||||
|
log(`${module}: sdl_cluster-workers topic not configured`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mqttUrl = `mqtt://127.0.0.1:${mqttCfg.mqtt_port}`;
|
||||||
|
const client = mqtt.connect(mqttUrl);
|
||||||
|
|
||||||
|
client.on('connect', () => {
|
||||||
|
log(`${module}: workers publisher connected to MQTT at ${mqttUrl}`);
|
||||||
|
|
||||||
|
publishWorkers(client, workersTopic);
|
||||||
|
setInterval(() => publishWorkers(client, workersTopic), workersInterval);
|
||||||
|
});
|
||||||
|
|
||||||
|
client.on('error', err => {
|
||||||
|
log(`${module}: workers publisher MQTT error: ${err}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function publishWorkers(client, topic) {
|
||||||
|
// Load current cluster state
|
||||||
|
const clusterState = loadClusterState(config);
|
||||||
|
|
||||||
|
const workersMsg = {
|
||||||
|
ts: new Date().toISOString(),
|
||||||
|
sdl_id: config.identity.sdl_id,
|
||||||
|
role: 'sdl-mgr',
|
||||||
|
host: config.identity.hostname,
|
||||||
|
type: 'cluster-workers',
|
||||||
|
msg: {
|
||||||
|
workers: clusterState.workers
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
client.publish(
|
||||||
|
topic,
|
||||||
|
JSON.stringify(workersMsg),
|
||||||
|
{ qos: 1, retain: true },
|
||||||
|
err => {
|
||||||
|
if (err) {
|
||||||
|
log(`${module}: failed to publish workers: ${err}`);
|
||||||
|
} else {
|
||||||
|
// log(`${module}: published workers to ${topic}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function startUdpBeacon() {
|
function startUdpBeacon() {
|
||||||
let sdlCfg = config.modules['sdl-mgr'];
|
let sdlCfg = config.modules['sdl-mgr'];
|
||||||
// log(`${module}: DEBUG: SDL config: ${JSON.stringify(sdlCfg, null, 2)}`, true);
|
// log(`${module}: DEBUG: SDL config: ${JSON.stringify(sdlCfg, null, 2)}`, true);
|
||||||
|
|
@ -547,6 +626,7 @@ function startUdpBeacon() {
|
||||||
// Entry point (ESM-safe)
|
// Entry point (ESM-safe)
|
||||||
// -------------------------------
|
// -------------------------------
|
||||||
startSDLStatusPub();
|
startSDLStatusPub();
|
||||||
|
startWorkersPub(); // ✅ Start workers publisher
|
||||||
startUdpBeacon();
|
startUdpBeacon();
|
||||||
loadClusterState(config);
|
loadClusterState(config);
|
||||||
startJoinHandler();
|
startJoinHandler();
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
"update_interval": {
|
"update_interval": {
|
||||||
"udp_beacon": 2000,
|
"udp_beacon": 2000,
|
||||||
"cluster_status": 10000,
|
"cluster_status": 10000,
|
||||||
"cluster_workers": 4000,
|
"cluster_workers": 10000,
|
||||||
"cluster_telemetry": 3000
|
"cluster_telemetry": 3000
|
||||||
},
|
},
|
||||||
"expiration_timeout": {
|
"expiration_timeout": {
|
||||||
|
|
|
||||||
|
|
@ -303,24 +303,54 @@ function renderModulesTable(msg) {
|
||||||
</tr>
|
</tr>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
// Workers stats
|
||||||
|
const workers = msg.msg.workers || { allocated: 0, available: 0, used: 0 };
|
||||||
sdl_html += `
|
sdl_html += `
|
||||||
<tr>
|
<tr>
|
||||||
<th><span class="fa fa-microchip" title="CPU Cores" style="font-size:1.2em"></span> CPU</th>
|
<th>SDL Workers (active/total)</th>
|
||||||
<td class="dash-val" style=" font-size:1em"></td>
|
<td class="dash-val" style="font-size:1em">
|
||||||
|
<span class="dash-val">${workers.available}</span> / ${workers.allocated}
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
// CPU resources
|
||||||
|
const cpus = msg.msg.resources?.cpus || { allocated: 0, available: 0, used: 0 };
|
||||||
|
sdl_html += `
|
||||||
|
<tr>
|
||||||
|
<th><span class="fa fa-microchip" title="CPU Cores" style="font-size:1.2em"></span> CPU Cores</th>
|
||||||
|
<td class="dash-val" style="font-size:1em">
|
||||||
|
<span class="dash-val">${cpus.available}</span> / ${cpus.allocated}
|
||||||
|
${cpus.used > 0 ? `<span style="font-size:0.8em">(${cpus.used} in use)</span>` : ''}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Memory resources
|
||||||
|
const memory = msg.msg.resources?.memory || { allocated: 0, available: 0, used: 0 };
|
||||||
|
const memAllocGB = (memory.allocated / 1024).toFixed(1);
|
||||||
|
const memAvailGB = (memory.available / 1024).toFixed(1);
|
||||||
|
const memUsedGB = memory.used > 0 ? (memory.used / 1024).toFixed(1) : 0;
|
||||||
|
|
||||||
sdl_html += `
|
sdl_html += `
|
||||||
<tr>
|
<tr>
|
||||||
<th><span class="fa fa-memory" title="RAM" style="font-size:1.2em"></span> RAM</th>
|
<th><span class="fa fa-memory" title="RAM" style="font-size:1.2em"></span> RAM</th>
|
||||||
<td class="dash-val" style=" font-size:1em"></td>
|
<td class="dash-val" style="font-size:1em">
|
||||||
|
<span class="dash-val">${memAvailGB}</span> / ${memAllocGB} GB
|
||||||
|
${memUsedGB > 0 ? `<span style="font-size:0.8em">(${memUsedGB} GB in use)</span>` : ''}
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
// GPU resources
|
||||||
|
const gpus = msg.msg.resources?.gpus || { allocated: 0, available: 0, used: 0 };
|
||||||
sdl_html += `
|
sdl_html += `
|
||||||
<tr>
|
<tr>
|
||||||
<th><span class="fa fa-dice-d20" title="GPU" style="font-size:1.2em"></span> GPU</th>
|
<th><span class="fa fa-dice-d20" title="GPU" style="font-size:1.2em"></span> GPU</th>
|
||||||
<td class="dash-val" style=" font-size:1em"></td>
|
<td class="dash-val" style="font-size:1em">
|
||||||
|
<span class="dash-val">${gpus.available}</span> / ${gpus.allocated}
|
||||||
|
${gpus.used > 0 ? `<span style="font-size:0.8em">(${gpus.used} in use)</span>` : ''}
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,11 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="col-4" id="dash-sdl-mgr-info">
|
<div class="col-4" id="dash-sdl-mgr-info">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-3" id="dash-modules">
|
<div class="col-2" id="dash-modules">
|
||||||
<div id="dash-modules-list"></div>
|
<div id="dash-modules-list"></div>
|
||||||
<div id="dash-modules-age"></div>
|
<div id="dash-modules-age"></div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-8" id="dash-sdl-wkrs">
|
||||||
|
<h5>SDL Workers</h5>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
Loading…
Reference in New Issue