From 6faa162f5561a005c2ea45f594bf7cfcbe10e1b6 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 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. PR-URL: https://github.com/nodejs/node/pull/32505 Reviewed-By: Anna Henningsen Reviewed-By: Gireesh Punathil Reviewed-By: Michaƫl Zasso Reviewed-By: James M Snell Reviewed-By: Trivikram Kamat --- 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 e89a309c79..213b72c19f 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 0887985973..20c028ce31 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 (!this.workers.has(worker.id)) + return false; - if (index === -1) - return false; // The worker wasn't sharing this handle. + this.workers.delete(worker.id); - this.workers.splice(index, 1); - - if (this.workers.length !== 0) + if (this.workers.size !== 0) return false; this.handle.close();