public static void loop()

in src/main/java/org/mariadb/jdbc/internal/protocol/AuroraProtocol.java [125:303]


  public static void loop(
      AuroraListener listener,
      final GlobalStateInfo globalInfo,
      final List<HostAddress> addresses,
      SearchFilter initialSearchFilter)
      throws SQLException {

    SearchFilter searchFilter = initialSearchFilter;
    AuroraProtocol protocol;
    Deque<HostAddress> loopAddresses = new ArrayDeque<>(addresses);
    if (loopAddresses.isEmpty()) {
      resetHostList(listener, loopAddresses);
    }

    int maxConnectionTry = listener.getRetriesAllDown();
    SQLException lastQueryException = null;
    HostAddress probableMasterHost = null;
    boolean firstLoop = true;
    while (!loopAddresses.isEmpty() || (!searchFilter.isFailoverLoop() && maxConnectionTry > 0)) {
      protocol = getNewProtocol(listener.getProxy(), globalInfo, listener.getUrlParser());

      if (listener.isExplicitClosed()
          || (!listener.isSecondaryHostFailReconnect() && !listener.isMasterHostFailReconnect())) {
        return;
      }
      maxConnectionTry--;

      try {
        HostAddress host = loopAddresses.pollFirst();
        if (host == null) {
          for (HostAddress hostAddress : listener.getUrlParser().getHostAddresses()) {
            if (!hostAddress.equals(listener.getClusterHostAddress())) {
              loopAddresses.add(hostAddress);
            }
          }
          // Use cluster last as backup
          if (listener.getClusterHostAddress() != null
              && (listener.getUrlParser().getHostAddresses().size() < 2
                  || loopAddresses.isEmpty())) {
            loopAddresses.add(listener.getClusterHostAddress());
          }

          host = loopAddresses.pollFirst();
        }
        protocol.setHostAddress(host);
        protocol.connect();

        if (listener.isExplicitClosed()) {
          protocol.close();
          return;
        }

        listener.removeFromBlacklist(protocol.getHostAddress());

        if (listener.isMasterHostFailReconnect() && protocol.isMasterConnection()) {
          // Look for secondary when only known endpoint is the cluster endpoint
          if (searchFilter.isFineIfFoundOnlyMaster()
              && listener.getUrlParser().getHostAddresses().size() <= 1
              && protocol.getHostAddress().equals(listener.getClusterHostAddress())) {
            listener.retrieveAllEndpointsAndSet(protocol);

            if (listener.getUrlParser().getHostAddresses().size() > 1) {
              // add newly discovered end-point to loop
              loopAddresses.addAll(listener.getUrlParser().getHostAddresses());
              // since there is more than one end point, reactivate connection to a read-only host
              searchFilter = new SearchFilter(false);
            }
          }

          if (foundMaster(listener, protocol, searchFilter)) {
            return;
          }

        } else if (!protocol.isMasterConnection()) {
          if (listener.isSecondaryHostFailReconnect()) {
            // in case cluster DNS is currently pointing to a slave host
            if (listener.getUrlParser().getHostAddresses().size() <= 1
                && protocol.getHostAddress().equals(listener.getClusterHostAddress())) {
              listener.retrieveAllEndpointsAndSet(protocol);

              if (listener.getUrlParser().getHostAddresses().size() > 1) {
                // add newly discovered end-point to loop
                loopAddresses.addAll(listener.getUrlParser().getHostAddresses());
                // since there is more than one end point, reactivate connection to a read-only host
                searchFilter = new SearchFilter(false);
              }
            } else {
              if (foundSecondary(listener, protocol, searchFilter)) {
                return;
              }
            }

          } else {
            try {
              if (listener.isSecondaryHostFailReconnect()
                  || (listener.isMasterHostFailReconnect() && probableMasterHost == null)) {
                probableMasterHost =
                    listener.searchByStartName(
                        protocol, listener.getUrlParser().getHostAddresses());
                if (probableMasterHost != null) {
                  loopAddresses.remove(probableMasterHost);
                  AuroraProtocol.searchProbableMaster(listener, globalInfo, probableMasterHost);
                  if (listener.isMasterHostFailReconnect()
                      && searchFilter.isFineIfFoundOnlySlave()) {
                    return;
                  }
                }
              }
            } finally {
              protocol.close();
            }
          }
        } else {
          protocol.close();
        }

      } catch (SQLException e) {
        lastQueryException = e;
        listener.addToBlacklist(protocol.getHostAddress());
      }

      if (!listener.isMasterHostFailReconnect() && !listener.isSecondaryHostFailReconnect()) {
        return;
      }

      // in case master not found but slave is , and allowing master down
      if (loopAddresses.isEmpty()
          && (listener.isMasterHostFailReconnect()
              && listener.urlParser.getOptions().allowMasterDownConnection
              && !listener.isSecondaryHostFailReconnect())) {
        return;
      }

      // on connection and all slaves have been tested, use master if on
      if (loopAddresses.isEmpty()
          && searchFilter.isInitialConnection()
          && !listener.isMasterHostFailReconnect()) {
        return;
      }

      // if server has try to connect to all host, and there is remaining master or slave that fail
      // add all servers back to continue looping until maxConnectionTry is reached
      if (loopAddresses.isEmpty() && !searchFilter.isFailoverLoop() && maxConnectionTry > 0) {
        resetHostList(listener, loopAddresses);
        if (firstLoop) {
          firstLoop = false;
        } else {
          try {
            // wait 250ms before looping through all connection another time
            Thread.sleep(250);
          } catch (InterruptedException interrupted) {
            // interrupted, continue
          }
        }
      }

      // Try to connect to the cluster if no other connection is good
      if (maxConnectionTry == 0
          && !loopAddresses.contains(listener.getClusterHostAddress())
          && listener.getClusterHostAddress() != null) {
        loopAddresses.add(listener.getClusterHostAddress());
      }
    }

    if (listener.isMasterHostFailReconnect() || listener.isSecondaryHostFailReconnect()) {
      String error = "No active connection found for replica";
      if (listener.isMasterHostFailReconnect()) {
        error = "No active connection found for master";
      }
      if (lastQueryException != null) {
        throw new SQLException(
            error,
            lastQueryException.getSQLState(),
            lastQueryException.getErrorCode(),
            lastQueryException);
      }
      throw new SQLException(error);
    }
  }