From 9ce8829689278e7304bc86f1dcd533b3680277a7 Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Fri, 8 Feb 2019 14:17:35 -0800 Subject: [PATCH] Added priorities in task queue. --- common.js | 27 ++++++++++++++++++--------- meshagent.js | 8 ++++---- package.json | 2 +- swarmserver.js | 4 ++-- views/default-min.handlebars | 2 +- views/default-mobile-min.handlebars | 2 +- views/default-mobile.handlebars | 2 +- views/default.handlebars | 10 +++++----- 8 files changed, 33 insertions(+), 24 deletions(-) diff --git a/common.js b/common.js index e2af5165..2d35597b 100644 --- a/common.js +++ b/common.js @@ -179,17 +179,19 @@ module.exports.checkPasswordRequirements = function(password, requirements) { // This is useful to limit the number of agents upgrading at the same time, to not swamp // the network with traffic. -// taskLimiterQueue.launch(somethingToDo, argument); +// taskLimiterQueue.launch(somethingToDo, argument, priority); // // function somethingToDo(argument, taskid, taskLimiterQueue) { // setTimeout(function () { taskLimiterQueue.completed(taskid); }, Math.random() * 2000); // } -module.exports.createTaskLimiterQueue = function(maxTasks, maxTaskTime, cleaningInterval) { - var obj = { maxTasks: maxTasks, maxTaskTime: (maxTaskTime * 1000), nextTaskId: 0, currentCount: 0, current: {}, pending: [], timer: null }; +module.exports.createTaskLimiterQueue = function (maxTasks, maxTaskTime, cleaningInterval) { + var obj = { maxTasks: maxTasks, maxTaskTime: (maxTaskTime * 1000), nextTaskId: 0, currentCount: 0, current: {}, pending: [[], [], []], timer: null }; // Add a task to the super queue - obj.launch = function (func, arg) { + // Priority: 0 = High, 1 = Medium, 2 = Low + obj.launch = function (func, arg, pri) { + if (typeof pri != 'number') { pri = 2; } if (obj.currentCount < obj.maxTasks) { // Run this task now const id = obj.nextTaskId++; @@ -201,7 +203,7 @@ module.exports.createTaskLimiterQueue = function(maxTasks, maxTaskTime, cleaning } else { // Hold this task //console.log('Holding'); - obj.pending.push({ func: func, arg: arg }); + obj.pending[pri].push({ func: func, arg: arg }); } } @@ -209,15 +211,22 @@ module.exports.createTaskLimiterQueue = function(maxTasks, maxTaskTime, cleaning obj.completed = function (taskid) { //console.log('Completed ' + taskid); if (obj.current[taskid]) { delete obj.current[taskid]; obj.currentCount--; } else { return; } - while ((obj.pending.length > 0) && (obj.currentCount < obj.maxTasks)) { + while ((obj.currentCount < obj.maxTasks) && ((obj.pending[0].length > 0) || (obj.pending[1].length > 0) || (obj.pending[2].length > 0))) { // Run this task now - const t = obj.pending.shift(), id = obj.nextTaskId++; + var t = null; + if (obj.pending[0].length > 0) { t = obj.pending[0].shift(); } + else if (obj.pending[1].length > 0) { t = obj.pending[1].shift(); } + else if (obj.pending[2].length > 0) { t = obj.pending[2].shift(); } + const id = obj.nextTaskId++; obj.current[id] = Date.now() + obj.maxTaskTime; obj.currentCount++; //console.log('PendingLaunch ' + id); t.func(t.arg, id, obj); // Start the task } - if ((obj.pending.length == 0) && (obj.timer != null)) { clearInterval(obj.timer); obj.timer = null; } // All done, clear the timer + if ((obj.pending[0].length == 0) && (obj.pending[1].length == 0) && (obj.pending[2].length == 0) && (obj.timer != null)) { + // All done, clear the timer + clearInterval(obj.timer); obj.timer = null; + } } // Look for long standing tasks and clean them up @@ -227,4 +236,4 @@ module.exports.createTaskLimiterQueue = function(maxTasks, maxTaskTime, cleaning } return obj; -} \ No newline at end of file +} diff --git a/meshagent.js b/meshagent.js index f6b559ca..6fe73f05 100644 --- a/meshagent.js +++ b/meshagent.js @@ -125,12 +125,12 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { //obj.send(obj.common.ShortToStr(10) + obj.common.ShortToStr(0) + meshcorehash + obj.parent.parent.defaultMeshCores[corename]); // MeshCommand_CoreModule, start core update //obj.parent.parent.debug(1, 'Updating code ' + corename); - // Update new core with task limiting so not to flood the server. + // Update new core with task limiting so not to flood the server. This is a high priority task. obj.parent.parent.taskLimiter.launch(function (argument, taskid, taskLimiterQueue) { obj.send(obj.common.ShortToStr(10) + obj.common.ShortToStr(0) + argument.hash + argument.core, function () { obj.parent.parent.taskLimiter.completed(taskid); }); // MeshCommand_CoreModule, start core update obj.parent.parent.debug(1, 'Updating code ' + argument.name); agentCoreIsStable(); - }, { hash: meshcorehash, core: obj.parent.parent.defaultMeshCores[corename], name: corename }); + }, { hash: meshcorehash, core: obj.parent.parent.defaultMeshCores[corename], name: corename }, 0); } obj.agentCoreCheck++; } @@ -169,7 +169,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { if ((msg.length == 52) && (obj.agentExeInfo != null) && (obj.agentExeInfo.update == true)) { var agenthash = obj.common.rstr2hex(msg.substring(4)).toLowerCase(); if ((agenthash != obj.agentExeInfo.hash) && (agenthash != '000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000')) { - // Mesh agent update required, do it using task limiter so not to flood the network. + // Mesh agent update required, do it using task limiter so not to flood the network. Medium priority task. obj.parent.parent.taskLimiter.launch(function (argument, taskid, taskLimiterQueue) { if (obj.nodeid != null) { obj.parent.parent.debug(1, 'Agent update required, NodeID=0x' + obj.nodeid.substring(0, 16) + ', ' + obj.agentExeInfo.desc); } obj.fs.open(obj.agentExeInfo.path, 'r', function (err, fd) { @@ -203,7 +203,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { obj.send(obj.agentUpdate.buf); // Command 14, mesh agent first data block } }); - }, null); + }, null, 1); } else { // Check the mesh core, if the agent is capable of running one diff --git a/package.json b/package.json index 2b957f8d..5beced05 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "meshcentral", - "version": "0.2.7-o", + "version": "0.2.7-p", "keywords": [ "Remote Management", "Intel AMT", diff --git a/swarmserver.js b/swarmserver.js index 1613dd0a..c974441b 100644 --- a/swarmserver.js +++ b/swarmserver.js @@ -215,11 +215,11 @@ module.exports.CreateSwarmServer = function (parent, db, args, certificates) { socket.tag.updatePtr = 0; //console.log('Performing legacy agent update from ' + nodeblock.agentversion + '.' + nodeblock.agenttype + ' to ' + socket.tag.update.ver + '.' + socket.tag.update.arch + ' on ' + nodeblock.agentname + '.'); - // Start the agent download using the task limiter so not to flood the server. + // Start the agent download using the task limiter so not to flood the server. Low priority task obj.parent.taskLimiter.launch(function (socket, taskid, taskLimiterQueue) { socket.tag.taskid = taskid; obj.SendCommand(socket, LegacyMeshProtocol.GETSTATE, common.IntToStr(5) + common.IntToStr(0)); // agent.SendQuery(5, 0); // Start the agent download - }, socket); + }, socket, 2); } else { //console.log('No legacy agent update for ' + nodeblock.agentversion + '.' + nodeblock.agenttype + ' on ' + nodeblock.agentname + '.'); } diff --git a/views/default-min.handlebars b/views/default-min.handlebars index d688c160..2efffb3e 100644 --- a/views/default-min.handlebars +++ b/views/default-min.handlebars @@ -1 +1 @@ - MeshCentral
{{{title}}}
{{{title2}}}

{{{logoutControl}}}

 

\ No newline at end of file + MeshCentral
{{{title}}}
{{{title2}}}

{{{logoutControl}}}

 

\ No newline at end of file diff --git a/views/default-mobile-min.handlebars b/views/default-mobile-min.handlebars index 4a5d9e3b..a7577f05 100644 --- a/views/default-mobile-min.handlebars +++ b/views/default-mobile-min.handlebars @@ -1 +1 @@ - MeshCentral
{{{title}}}
{{{title2}}}
\ No newline at end of file + MeshCentral
{{{title}}}
{{{title2}}}
\ No newline at end of file diff --git a/views/default-mobile.handlebars b/views/default-mobile.handlebars index f8de00a1..e049ea31 100644 --- a/views/default-mobile.handlebars +++ b/views/default-mobile.handlebars @@ -249,7 +249,7 @@
Device Groups - ( New ) + ( New )

diff --git a/views/default.handlebars b/views/default.handlebars index 76a44d3a..d5bad4fe 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -3312,7 +3312,7 @@ // Add node name var nname = EscapeHtml(node.name); if (nname.length == 0) { nname = 'None'; } - if ((meshrights & 4) != 0) { nname = '' + nname + ' '; } + if ((meshrights & 4) != 0) { nname = '' + nname + ' '; } QH('p10deviceName', nname); QH('p11deviceName', nname); QH('p12deviceName', nname); @@ -3346,7 +3346,7 @@ // Attribute: Description var description = node.desc?EscapeHtml(node.desc):"None"; if ((meshrights & 4) != 0) { - x += addDeviceAttribute('Description', '' + description + ' '); + x += addDeviceAttribute('Description', '' + description + ' '); } else { x += addDeviceAttribute('Description', description); } @@ -3421,7 +3421,7 @@ // Node grouping tags var groupingTags = 'None'; if (node.tags != null) { groupingTags = ''; for (var i in node.tags) { groupingTags += '' + node.tags[i] + ''; } } - x += addDeviceAttribute('Tags', '' + groupingTags + ' '); + x += addDeviceAttribute('Tags', '' + groupingTags + ' '); x += '
'; // Show action button, only show if we have permissions 4, 8, 64 @@ -6360,7 +6360,7 @@ var x = '
'; var email = user.email?EscapeHtml(user.email):'Not set', everify = ''; if (serverinfo.emailcheck) { everify = ((user.emailVerified == true)?'🗸 ':'🗴 '); } - x += addDeviceAttribute('Email', everify + "" + email + ''); + x += addDeviceAttribute('Email', everify + "" + email + ''); x += addDeviceAttribute('Server Rights', "" + msg + ""); if (user.quota) x += addDeviceAttribute('Server Quota', EscapeHtml(parseInt(user.quota) / 1024) + ' k'); x += addDeviceAttribute('Creation', new Date(user.creation * 1000).toLocaleString()); @@ -6919,7 +6919,7 @@ function putstore(name, val) { try { if (typeof (localStorage) === 'undefined') return; localStorage.setItem(name, val); } catch (e) { } } function getstore(name, val) { try { if (typeof (localStorage) === 'undefined') return val; var v = localStorage.getItem(name); if ((v == null) || (v == null)) return val; return v; } catch (e) { return val; } } //function addLink(x, f) { return "♦ " + x + ""; } - function addLink(x, f) { return "" + x + " "; } + function addLink(x, f) { return "" + x + " "; } function addLinkConditional(x, f, c) { if (c) return addLink(x, f); return x; } function haltEvent(e) { if (e.preventDefault) e.preventDefault(); if (e.stopPropagation) e.stopPropagation(); return false; } function addOption(q, t, i) { var option = document.createElement("option"); option.text = t; option.value = i; Q(q).add(option); }