* Acquires a new connection and refreshes topology and keyspace metadata. * When it fails obtaining a connection and there aren't any more hosts, it schedules reconnection. * When it fails obtaining the metadata, it marks connection and/or host unusable and retries using the same
(hostIterator)
| 453 | * @param {Iterator<Host>} [hostIterator] |
| 454 | */ |
| 455 | async _refresh(hostIterator) { |
| 456 | if (this._isShuttingDown) { |
| 457 | this.log('info', 'The ControlConnection will not be refreshed as the Client is being shutdown'); |
| 458 | return; |
| 459 | } |
| 460 | |
| 461 | // Reset host and connection |
| 462 | this.host = null; |
| 463 | this.connection = null; |
| 464 | |
| 465 | try { |
| 466 | if (!hostIterator) { |
| 467 | this.log('info', 'Trying to acquire a connection to a new host'); |
| 468 | this._triedHosts = {}; |
| 469 | hostIterator = await promiseUtils.newQueryPlan(this._profileManager.getDefaultLoadBalancing(), null, null); |
| 470 | } |
| 471 | |
| 472 | await this._refreshControlConnection(hostIterator); |
| 473 | } catch (err) { |
| 474 | // There was a failure obtaining a connection or during metadata retrieval |
| 475 | this.log('error', 'ControlConnection failed to acquire a connection', err); |
| 476 | |
| 477 | if (!this._isShuttingDown) { |
| 478 | const delay = this._reconnectionSchedule.next().value; |
| 479 | this.log('warning', `ControlConnection could not reconnect, scheduling reconnection in ${delay}ms`); |
| 480 | setTimeout(() => this._refresh(), delay); |
| 481 | this.emit('newConnection', err); |
| 482 | } |
| 483 | |
| 484 | return; |
| 485 | } |
| 486 | |
| 487 | this.log('info',`ControlConnection connected to ${this.connection.endpointFriendlyName}`); |
| 488 | |
| 489 | try { |
| 490 | await this._refreshHosts(false, true); |
| 491 | |
| 492 | await this._registerToConnectionEvents(); |
| 493 | } catch (err) { |
| 494 | this.log('error', 'ControlConnection failed to retrieve topology and keyspaces information', err); |
| 495 | this._triedHosts[this.connection.endpoint] = err; |
| 496 | |
| 497 | if (err.isSocketError && this.host) { |
| 498 | this.host.removeFromPool(this.connection); |
| 499 | } |
| 500 | |
| 501 | // Retry the whole thing with the same query plan |
| 502 | return await this._refresh(hostIterator); |
| 503 | } |
| 504 | |
| 505 | this._reconnectionSchedule = this._reconnectionPolicy.newSchedule(); |
| 506 | this._setHealthListeners(this.host, this.connection); |
| 507 | this.emit('newConnection', null, this.connection, this.host); |
| 508 | |
| 509 | this.log('info', `ControlConnection connected to ${this.connection.endpointFriendlyName} and up to date`); |
| 510 | } |
| 511 | |
| 512 | /** |
no test coverage detected