async getVerifiedReaderClient()

in common/lib/plugins/aurora_initial_connection_strategy_plugin.ts [178:261]


  async getVerifiedReaderClient<T>(props: Map<string, any>, isInitialConnection: boolean, connectFunc: () => Promise<T>): Promise<any> {
    if (!this.hostListProviderService) {
      throw new AwsWrapperError(Messages.get("HostListProviderService.notFound")); // should not be reached
    }

    const retryDelayMs = WrapperProperties.OPEN_CONNECTION_RETRY_INTERVAL_MS.get(props);
    const endTimeMs = Date.now() + WrapperProperties.OPEN_CONNECTION_RETRY_TIMEOUT_MS.get(props);

    let readerCandidateClient: any;
    let readerCandidate: HostInfo | void | null;

    while (Date.now() < endTimeMs) {
      readerCandidateClient = null;
      readerCandidate = null;

      try {
        readerCandidate = this.getReader(props);
        // convert into null if undefined
        readerCandidate = readerCandidate ?? null;

        if (readerCandidate === null || this.rdsUtils.isRdsClusterDns(readerCandidate.host)) {
          // Reader is not found. It seems that topology is outdated.
          readerCandidateClient = await connectFunc();
          await this.pluginService.forceRefreshHostList(readerCandidateClient);
          readerCandidate = await this.pluginService.identifyConnection(readerCandidateClient);

          if (readerCandidate) {
            if (readerCandidate.role !== HostRole.READER) {
              if (this.hasNoReaders()) {
                // It seems that cluster has no readers. Simulate Aurora reader cluster endpoint logic
                // and return the current (writer) client.
                if (isInitialConnection) {
                  this.hostListProviderService.setInitialConnectionHostInfo(readerCandidate);
                }
                return readerCandidateClient;
              }
              await this.pluginService.abortTargetClient(readerCandidateClient);
              await sleep(retryDelayMs);
              continue;
            }

            // Reader connection is valid and verified.
            if (isInitialConnection) {
              this.hostListProviderService.setInitialConnectionHostInfo(readerCandidate);
            }
          } else {
            logger.debug("Reader candidate not found");
          }
          return readerCandidateClient;
        }
        readerCandidateClient = await this.pluginService.connect(readerCandidate, props);

        if ((await this.pluginService.getHostRole(readerCandidateClient)) !== HostRole.READER) {
          // If the new connection resolves to a writer instance, this means the topology is outdated.
          // Force refresh to update the topology.
          await this.pluginService.forceRefreshHostList(readerCandidateClient);

          if (this.hasNoReaders()) {
            // It seems that cluster has no readers. Simulate Aurora reader cluster endpoint logic
            // and return the current (writer) client.
            if (isInitialConnection) {
              this.hostListProviderService.setInitialConnectionHostInfo(readerCandidate);
            }
            return readerCandidateClient;
          }
          await this.pluginService.abortTargetClient(readerCandidateClient);
          await sleep(retryDelayMs);
          continue;
        }
        // Reader connection is valid and verified.
        if (isInitialConnection) {
          this.hostListProviderService.setInitialConnectionHostInfo(readerCandidate);
        }
        return readerCandidateClient;
      } catch (error: any) {
        await this.pluginService.abortTargetClient(readerCandidateClient);
        if (this.pluginService.isLoginError(error) || !readerCandidate) {
          throw error;
        } else if (readerCandidate) {
          this.pluginService.setAvailability(readerCandidate.allAliases, HostAvailability.NOT_AVAILABLE);
        }
      }
    }
  }