Implement Node Monitor Service
- Check in with online nodes every n ms - Update nodes that do not reply - Added node object record helper - Updated mysql wrapper for updating node info to accept bool or number
This commit is contained in:
@@ -2,31 +2,42 @@
|
||||
const { DebugBuilder } = require("../utilities/debugBuilder.js");
|
||||
const log = new DebugBuilder("server", "nodesController");
|
||||
// Utilities
|
||||
const mysqlHander = require("../utilities/mysqlHandler");
|
||||
const {getAllNodes, addNewNode, updateNodeInfo, getNodeInfoFromId, getOnlineNodes } = require("../utilities/mysqlHandler");
|
||||
const utils = require("../utilities/utils");
|
||||
const { sendHttpRequest, requestOptions } = require("../utilities/httpRequests.js");
|
||||
const { nodeObject } = require("../utilities/recordHelper.js");
|
||||
|
||||
const refreshInterval = process.env.NODE_MONITOR_REFRESH_INTERVAL ?? 1200000;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {*} req
|
||||
* @param {*} res
|
||||
*/
|
||||
exports.listAllNodes = async (req, res) => {
|
||||
mysqlHander.getAllNodes((allNodes) => {
|
||||
getAllNodes((allNodes) => {
|
||||
res.status(200).json({
|
||||
"nodes_online": allNodes
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Add a new node to the
|
||||
// Add a new node to the storage
|
||||
exports.newNode = async (req, res) => {
|
||||
if (!req.body.name) return res.send(400)
|
||||
|
||||
try {
|
||||
// Try to add the new user with defaults if missing options
|
||||
mysqlHander.addNewNode({
|
||||
'name': req.body.name,
|
||||
'ip': req.body.ip ?? null,
|
||||
'port': req.body.port ?? null,
|
||||
'location': req.body.location ?? null,
|
||||
'nearbySystems': req.body.nearbySystems ?? null,
|
||||
'online': req.body.online ?? 0
|
||||
}, (queryResults) => {
|
||||
const newNode = new nodeObject({
|
||||
_name: req.body.name,
|
||||
_ip: req.body.ip ?? null,
|
||||
_port: req.body.port ?? null,
|
||||
_location: req.body.location ?? null,
|
||||
_nearbySystems: req.body.nearbySystems ?? null,
|
||||
_online: req.body.online ?? 0
|
||||
});
|
||||
|
||||
addNewNode(newNode, (queryResults) => {
|
||||
// Send back a success if the user has been added and the ID for the client to keep track of
|
||||
res.status(202).json({"nodeId": queryResults.insertId});
|
||||
})
|
||||
@@ -44,7 +55,7 @@ exports.newNode = async (req, res) => {
|
||||
// Get the known info for the node specified
|
||||
exports.getNodeInfo = async (req, res) => {
|
||||
if (!req.query.id) return res.status(400).json("No id specified");
|
||||
mysqlHander.getNodeInfoFromId(req.query.id, (nodeInfo) => {
|
||||
getNodeInfoFromId(req.query.id, (nodeInfo) => {
|
||||
res.status(200).json(nodeInfo);
|
||||
})
|
||||
}
|
||||
@@ -52,29 +63,77 @@ exports.getNodeInfo = async (req, res) => {
|
||||
// Updates the information received from the client based on ID
|
||||
exports.nodeCheckIn = async (req, res) => {
|
||||
if (!req.body.id) return res.status(400).json("No id specified");
|
||||
mysqlHander.getNodeInfoFromId(req.body.id, (nodeInfo) => {
|
||||
let nodeObject = {};
|
||||
getNodeInfoFromId(req.body.id, (nodeInfo) => {
|
||||
let checkInObject = new nodeObject();
|
||||
// Convert the DB systems buffer to a JSON object to be worked with
|
||||
nodeInfo.nearbySystems = utils.BufferToJson(nodeInfo.nearbySystems)
|
||||
// Convert the online status to a boolean to be worked with
|
||||
nodeInfo.online = nodeInfo.online !== 0;
|
||||
|
||||
if (req.body.name && req.body.name !== nodeInfo.name) nodeObject.name = req.body.name
|
||||
if (req.body.ip && req.body.ip !== nodeInfo.ip) nodeObject.ip = req.body.ip
|
||||
if (req.body.port && req.body.port !== nodeInfo.port) nodeObject.port = req.body.port
|
||||
if (req.body.location && req.body.location !== nodeInfo.location) nodeObject.location = req.body.location
|
||||
if (req.body.nearbySystems && JSON.stringify(req.body.nearbySystems) !== JSON.stringify(nodeInfo.nearbySystems)) nodeObject.nearbySystems = req.body.nearbySystems
|
||||
if (req.body.online && req.body.online !== nodeInfo.online) nodeObject.online = req.body.online
|
||||
if (req.body.name && req.body.name !== nodeInfo.name) checkInObject.name = req.body.name
|
||||
if (req.body.ip && req.body.ip !== nodeInfo.ip) checkInObject.ip = req.body.ip
|
||||
if (req.body.port && req.body.port !== nodeInfo.port) checkInObject.port = req.body.port
|
||||
if (req.body.location && req.body.location !== nodeInfo.location) checkInObject.location = req.body.location
|
||||
if (req.body.nearbySystems && JSON.stringify(req.body.nearbySystems) !== JSON.stringify(nodeInfo.nearbySystems)) checkInObject.nearbySystems = req.body.nearbySystems
|
||||
if (req.body.online && req.body.online !== nodeInfo.online) checkInObject.online = req.body.online
|
||||
|
||||
// If no changes are made tell the client
|
||||
if (Object.keys(nodeObject).length === 0) return res.status(200).json("No keys updated");
|
||||
if (Object.keys(checkInObject).length === 0) return res.status(200).json("No keys updated");
|
||||
|
||||
log.INFO("Updating the following keys for ID: ", req.body.id, nodeObject);
|
||||
log.INFO("Updating the following keys for ID: ", req.body.id, checkInObject);
|
||||
// Adding the ID key to the body so that the client can double-check their ID
|
||||
nodeObject.id = req.body.id;
|
||||
mysqlHander.updateNodeInfo(nodeObject, () => {
|
||||
return res.status(202).json({"updatedKeys": nodeObject});
|
||||
checkInObject.id = req.body.id;
|
||||
updateNodeInfo(checkInObject, () => {
|
||||
return res.status(202).json({"updatedKeys": checkInObject});
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
exports.nodeMonitorService = class nodeMonitorService {
|
||||
constructor() {
|
||||
}
|
||||
|
||||
async start(){
|
||||
// Wait for the a portion of the refresh period before checking in with the nodes, so the rest of the bot can start
|
||||
await new Promise(resolve => setTimeout(resolve, refreshInterval/10));
|
||||
|
||||
log.INFO("Starting Node Monitor Service");
|
||||
// Check in before starting the infinite loop
|
||||
await this.checkInWithOnlineNodes();
|
||||
|
||||
|
||||
while(true){
|
||||
// Wait for the refresh interval, then wait for the posts to return, then wait a quarter of the refresh interval to make sure everything is cleared up
|
||||
await new Promise(resolve => setTimeout(resolve, refreshInterval));
|
||||
await this.checkInWithOnlineNodes();
|
||||
await new Promise(resolve => setTimeout(resolve, refreshInterval / 4));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
async checkInWithOnlineNodes(){
|
||||
getOnlineNodes((nodes) => {
|
||||
log.DEBUG("Online Nodes: ", nodes);
|
||||
for (const node of nodes) {
|
||||
const reqOptions = new requestOptions("/client/requestCheckIn", "GET", node.ip, node.port)
|
||||
const request = sendHttpRequest(reqOptions, "", (responseObj) => {
|
||||
if (responseObj) {
|
||||
log.DEBUG("Response from: ", node.name, responseObj);
|
||||
}
|
||||
else {
|
||||
log.DEBUG("No response from node, assuming it's offline");
|
||||
const offlineNode = new nodeObject({ _online: 0, _id: node.id });
|
||||
log.DEBUG("Offline node update object: ", offlineNode);
|
||||
updateNodeInfo(offlineNode, (sqlResponse) => {
|
||||
if (!sqlResponse) log.ERROR("No response from SQL object");
|
||||
|
||||
log.DEBUG("Updated node: ", sqlResponse);
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
return;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user