From e8f1115f6f7a6ae0e07fe9f04cbb00b4d927a776 Mon Sep 17 00:00:00 2001 From: Yash Ladha Date: Thu, 26 Mar 2020 19:31:09 +0530 Subject: [PATCH] lib: changed functional logic in cluster schedulers Free pool in round_robin scheduler is implemented as an array. There were constant lookups being for distributing load on other workers in free pool. Reimplementing in Map will create will be more performant as compared to Array implementation. This was done for all in past but free wasn't implemented at that time. --- lib/internal/cluster/round_robin_handle.js | 19 ++++++++++--------- lib/internal/cluster/shared_handle.js | 17 ++++++++--------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/lib/internal/cluster/round_robin_handle.js b/lib/internal/cluster/round_robin_handle.js index e89a309c79844c..213b72c19f4273 100644 --- a/lib/internal/cluster/round_robin_handle.js +++ b/lib/internal/cluster/round_robin_handle.js @@ -1,6 +1,7 @@ 'use strict'; const { + ArrayIsArray, Boolean, Map, } = primordials; @@ -15,7 +16,7 @@ module.exports = RoundRobinHandle; function RoundRobinHandle(key, address, port, addressType, fd, flags) { this.key = key; this.all = new Map(); - this.free = []; + this.free = new Map(); this.handles = []; this.handle = null; this.server = net.createServer(assert.fail); @@ -73,10 +74,7 @@ RoundRobinHandle.prototype.remove = function(worker) { if (!existed) return false; - const index = this.free.indexOf(worker); - - if (index !== -1) - this.free.splice(index, 1); + this.free.delete(worker.id); if (this.all.size !== 0) return false; @@ -93,21 +91,24 @@ RoundRobinHandle.prototype.remove = function(worker) { RoundRobinHandle.prototype.distribute = function(err, handle) { this.handles.push(handle); - const worker = this.free.shift(); + const [ workerEntry ] = this.free; - if (worker) + if (ArrayIsArray(workerEntry)) { + const [ workerId, worker ] = workerEntry; + this.free.delete(workerId); this.handoff(worker); + } }; RoundRobinHandle.prototype.handoff = function(worker) { - if (this.all.has(worker.id) === false) { + if (!this.all.has(worker.id)) { return; // Worker is closing (or has closed) the server. } const handle = this.handles.shift(); if (handle === undefined) { - this.free.push(worker); // Add to ready queue again. + this.free.set(worker.id, worker); // Add to ready queue again. return; } diff --git a/lib/internal/cluster/shared_handle.js b/lib/internal/cluster/shared_handle.js index 088798597382f8..20c028ce313d40 100644 --- a/lib/internal/cluster/shared_handle.js +++ b/lib/internal/cluster/shared_handle.js @@ -1,4 +1,5 @@ 'use strict'; +const { Map } = primordials; const assert = require('internal/assert'); const dgram = require('internal/dgram'); const net = require('net'); @@ -7,7 +8,7 @@ module.exports = SharedHandle; function SharedHandle(key, address, port, addressType, fd, flags) { this.key = key; - this.workers = []; + this.workers = new Map(); this.handle = null; this.errno = 0; @@ -24,20 +25,18 @@ function SharedHandle(key, address, port, addressType, fd, flags) { } SharedHandle.prototype.add = function(worker, send) { - assert(!this.workers.includes(worker)); - this.workers.push(worker); + assert(!this.workers.has(worker.id)); + this.workers.set(worker.id, worker); send(this.errno, null, this.handle); }; SharedHandle.prototype.remove = function(worker) { - const index = this.workers.indexOf(worker); - - if (index === -1) - return false; // The worker wasn't sharing this handle. + if (!this.workers.has(worker.id)) + return false; - this.workers.splice(index, 1); + this.workers.delete(worker.id); - if (this.workers.length !== 0) + if (this.workers.size !== 0) return false; this.handle.close();