diff --git a/lib/control-connection.js b/lib/control-connection.js index fd707529..3cbfe22d 100644 --- a/lib/control-connection.js +++ b/lib/control-connection.js @@ -99,8 +99,8 @@ class ControlConnection extends events.EventEmitter { // Timeout used for delayed handling of topology changes this._topologyChangeTimeout = null; - // Timeout used for delayed handling of node status changes - this._nodeStatusChangeTimeout = null; + // Map of host endpoint strings to their pending status change timeouts + this._nodeStatusChangeTimers = new Map(); if (context && context.borrowHostConnection) { this._borrowHostConnection = context.borrowHostConnection; @@ -598,14 +598,23 @@ class ControlConnection extends events.EventEmitter { self.log('warning', 'Received status change event but host was not found: ' + addressToTranslate); return; } + + const existingTimer = self._nodeStatusChangeTimers.get(endPoint); + if (existingTimer) { + clearTimeout(existingTimer); + self._nodeStatusChangeTimers.delete(endPoint); + } + const distance = self._profileManager.getDistance(host); if (event.up) { if (distance === types.distance.ignored) { return host.setUp(true); } - clearTimeout(self._nodeStatusChangeTimeout); // Waits a couple of seconds before marking it as UP - self._nodeStatusChangeTimeout = setTimeout(() => host.checkIsUp(), newNodeDelay); + self._nodeStatusChangeTimers.set(endPoint, setTimeout(() => { + self._nodeStatusChangeTimers.delete(endPoint); + host.checkIsUp(); + }, newNodeDelay)); return; } // marked as down @@ -998,7 +1007,10 @@ class ControlConnection extends events.EventEmitter { this.emit('newConnection', new errors.DriverError('ControlConnection is being shutdown')); // Cancel timers clearTimeout(this._topologyChangeTimeout); - clearTimeout(this._nodeStatusChangeTimeout); + for (const timer of this._nodeStatusChangeTimers.values()) { + clearTimeout(timer); + } + this._nodeStatusChangeTimers.clear(); } /**