async failoverWriter()

in common/lib/plugins/failover2/failover2_plugin.ts [373:433]


  async failoverWriter() {
    const telemetryFactory = this.pluginService.getTelemetryFactory();
    const telemetryContext = telemetryFactory.openTelemetryContext(Failover2Plugin.TELEMETRY_WRITER_FAILOVER, TelemetryTraceLevel.NESTED);
    this.failoverWriterTriggeredCounter.inc();

    try {
      logger.debug(Messages.get("Failover.startWriterFailover"));
      await telemetryContext.start(async () => {
        if (!(await this.pluginService.forceMonitoringRefresh(true, this.failoverTimeoutSettingMs))) {
          // Unable to establish SQL connection to writer node.
          this.logAndThrowError(Messages.get("Failover2.unableToFetchTopology"));
        }

        const hosts: HostInfo[] = this.pluginService.getAllHosts();

        let writerCandidateClient: ClientWrapper = null;
        const writerCandidateHostInfo: HostInfo = hosts.find((x) => x.role === HostRole.WRITER);

        const allowedHosts = this.pluginService.getHosts();
        if (!allowedHosts.some((hostInfo: HostInfo) => hostInfo.host === writerCandidateHostInfo?.host)) {
          const failoverErrorMessage = Messages.get(
            "Failover.newWriterNotAllowed",
            writerCandidateHostInfo ? writerCandidateHostInfo.host : "<null>",
            logTopology(allowedHosts, "[Failover.newWriterNotAllowed] ")
          );
          logger.error(failoverErrorMessage);
          throw new FailoverFailedError(failoverErrorMessage);
        }

        if (writerCandidateHostInfo) {
          try {
            writerCandidateClient = await this.createConnectionForHost(writerCandidateHostInfo);
          } catch (err) {
            this.logAndThrowError(Messages.get("Failover.unableToConnectToWriterDueToError", writerCandidateHostInfo.host, err.message));
          }
        }

        if (!writerCandidateClient) {
          this.logAndThrowError(Messages.get("Failover.unableToConnectToWriter"));
        }

        if ((await this.pluginService.getHostRole(writerCandidateClient)) !== HostRole.WRITER) {
          try {
            await writerCandidateClient?.end();
          } catch (error) {
            // Do nothing.
          }
          this.logAndThrowError(Messages.get("Failover2.failoverWriterConnectedToReader", writerCandidateHostInfo.host));
        }

        await this.pluginService.abortCurrentClient();
        await this.pluginService.setCurrentClient(writerCandidateClient, writerCandidateHostInfo);
        logger.info(Messages.get("Failover.establishedConnection", writerCandidateHostInfo.host));
        this.failoverWriterSuccessCounter.inc();
      });
    } finally {
      if (this.telemetryFailoverAdditionalTopTraceSetting) {
        await telemetryFactory.postCopy(telemetryContext, TelemetryTraceLevel.FORCE_TOP_LEVEL);
      }
    }
  }