1
0
Fork 0
mirror of https://github.com/Ylianst/MeshCentral.git synced 2025-03-09 15:40:18 +00:00

Added server instrumentation

This commit is contained in:
Ylian Saint-Hilaire 2019-05-01 15:02:03 -07:00
parent f73276bdea
commit d387a0cc8b
7 changed files with 258 additions and 27 deletions

View file

@ -549,14 +549,47 @@ module.exports.CertificateOperations = function (parent) {
// Accelerators, used to dispatch work to other processes
const fork = require("child_process").fork;
const program = require("path").join(__dirname, "meshaccelerator.js");
const acceleratorTotalCount = require("os").cpus().length;
const acceleratorTotalCount = 1; //require("os").cpus().length; // TODO: Check if this accelerator can scale.
var acceleratorCreateCount = acceleratorTotalCount;
var freeAccelerators = [];
var pendingAccelerator = [];
obj.acceleratorCertStore = null;
// Accelerator Stats
var getAcceleratorFuncCalls = 0;
var acceleratorStartFuncCall = 0;
var acceleratorPerformSignatureFuncCall = 0;
var acceleratorPerformSignaturePushFuncCall = 0;
var acceleratorPerformSignatureRunFuncCall = 0;
var acceleratorMessage = 0;
var acceleratorMessageException = 0;
var acceleratorMessageLastException = null;
var acceleratorException = 0;
var acceleratorLastException = null;
// Get stats about the accelerators
obj.getAcceleratorStats = function () {
return {
acceleratorTotalCount: acceleratorTotalCount,
acceleratorCreateCount: acceleratorCreateCount,
freeAccelerators: freeAccelerators.length,
pendingAccelerator: pendingAccelerator.length,
getAcceleratorFuncCalls: getAcceleratorFuncCalls,
startFuncCall: acceleratorStartFuncCall,
performSignatureFuncCall: acceleratorPerformSignatureFuncCall,
performSignaturePushFuncCall: acceleratorPerformSignaturePushFuncCall,
performSignatureRunFuncCall: acceleratorPerformSignatureRunFuncCall,
message: acceleratorMessage,
messageException: acceleratorMessageException,
messageLastException: acceleratorMessageLastException,
exception: acceleratorException,
lastException: acceleratorLastException
};
}
// Create a new accelerator module
obj.getAccelerator = function () {
getAcceleratorFuncCalls++;
if (obj.acceleratorCertStore == null) { return null; }
if (freeAccelerators.length > 0) { return freeAccelerators.pop(); }
if (acceleratorCreateCount > 0) {
@ -564,23 +597,26 @@ module.exports.CertificateOperations = function (parent) {
var accelerator = fork(program, [], { stdio: ["pipe", "pipe", "pipe", "ipc"] });
accelerator.accid = acceleratorCreateCount;
accelerator.on("message", function (message) {
this.func(this.tag, message);
delete this.tag;
if (pendingAccelerator.length > 0) {
var x = pendingAccelerator.shift();
if (x.tag) { this.tag = x.tag; delete x.tag; }
accelerator.send(x);
} else { freeAccelerators.push(this); }
acceleratorMessage++;
try { this.func(this.tag, message); } catch (ex) { acceleratorMessageException++; acceleratorMessageLastException = ex; }
try {
delete this.tag;
if (pendingAccelerator.length > 0) {
var x = pendingAccelerator.shift();
if (x.tag) { this.tag = x.tag; delete x.tag; }
accelerator.send(x);
} else { freeAccelerators.push(this); }
} catch (ex) { acceleratorException++; acceleratorLastException = ex; }
});
accelerator.send({ action: "setState", certs: obj.acceleratorCertStore });
return accelerator;
}
return null;
};
// Set the state of the accelerators. This way, we don"t have to send certificate & keys to them each time.
obj.acceleratorStart = function (certificates) {
acceleratorStartFuncCall++;
if (obj.acceleratorCertStore != null) { console.error("ERROR: Accelerators can only be started once."); return; }
obj.acceleratorCertStore = [{ cert: certificates.agent.cert, key: certificates.agent.key }];
if (certificates.swarmserver != null) { obj.acceleratorCertStore.push({ cert: certificates.swarmserver.cert, key: certificates.swarmserver.key }); }
@ -588,19 +624,22 @@ module.exports.CertificateOperations = function (parent) {
// Perform any RSA signature, just pass in the private key and data.
obj.acceleratorPerformSignature = function (privatekey, data, tag, func) {
acceleratorPerformSignatureFuncCall++;
if (acceleratorTotalCount <= 1) {
// No accelerators available
if (typeof privatekey == "number") { privatekey = obj.acceleratorCertStore[privatekey].key; }
const sign = obj.crypto.createSign("SHA384");
sign.end(Buffer.from(data, "binary"));
func(tag, sign.sign(privatekey).toString("binary"));
try { func(tag, sign.sign(privatekey).toString("binary")); } catch (ex) { acceleratorMessageException++; acceleratorMessageLastException = ex; }
} else {
var acc = obj.getAccelerator();
if (acc == null) {
// Add to pending accelerator workload
acceleratorPerformSignaturePushFuncCall++;
pendingAccelerator.push({ action: "sign", key: privatekey, data: data, tag: tag });
} else {
// Send to accelerator now
acceleratorPerformSignatureRunFuncCall++;
acc.func = func;
acc.tag = tag;
acc.send({ action: "sign", key: privatekey, data: data });