From 94251c463ba57cac47e9b3a051b2e02527d9b156 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 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();