async refreshTopologyAndConnectToNewWriter()

in common/lib/plugins/failover/writer_failover_handler.ts [379:422]


  async refreshTopologyAndConnectToNewWriter(): Promise<boolean> {
    const allowOldWriter: boolean = this.pluginService.getDialect().getFailoverRestrictions().includes(FailoverRestriction.ENABLE_WRITER_IN_TASK_B);

    while (this.pluginService.getCurrentClient() && Date.now() < this.endTime && !this.failoverCompleted) {
      try {
        if (this.currentReaderTargetClient) {
          await this.pluginService.forceRefreshHostList(this.currentReaderTargetClient);
        }
        const topology = this.pluginService.getAllHosts();

        if (topology && topology.length > 0) {
          if (topology.length === 1) {
            // The currently connected reader is in a middle of failover. It's not yet connected
            // to a new writer and works in as "standalone" host. The handler needs to
            // wait till the reader gets connected to entire cluster and fetch a proper
            // cluster topology.

            // do nothing
            logger.info(
              Messages.get("ClusterAwareWriterFailoverHandler.standaloneHost", this.currentReaderHost == null ? "" : this.currentReaderHost.url)
            );
          } else {
            this.currentTopology = topology;
            const writerCandidate = getWriter(this.currentTopology);
            if (writerCandidate && (allowOldWriter || !this.isSame(writerCandidate, this.originalWriterHost))) {
              // new writer is available, and it's different from the previous writer
              logger.debug(logTopology(this.currentTopology, "[Task B] "));
              if (await this.connectToWriter(writerCandidate)) {
                return true;
              }
            }
          }
        }
      } catch (error: any) {
        logger.info(Messages.get("ClusterAwareWriterFailoverHandler.taskBEncounteredError", error.message));
        return false;
      }

      await new Promise((resolve) => {
        this.connectToReaderTimeoutId = setTimeout(resolve, this.readTopologyIntervalMs);
      });
    }
    return false;
  }