public void run() {
   if (!explicitClosed && hasHostFail()) {
     if (listener.shouldReconnect()) {
       try {
         if (currentConnectionAttempts.get() >= urlParser.getOptions().failoverLoopRetries) {
           throw new QueryException(
               "Too many reconnection attempts (" + urlParser.getOptions().retriesAllDown + ")");
         }
         SearchFilter filter = getFilterForFailedHost();
         filter.setUniqueLoop(true);
         listener.reconnectFailedConnection(filter);
         // reconnection done !
         stopFailover();
       } catch (Exception e) {
         // FailLoop search connection failed
       }
     } else {
       if (currentConnectionAttempts.get() > urlParser.getOptions().retriesAllDown) {
         // stopping failover after too many attemps
         stopFailover();
       }
     }
   } else {
     stopFailover();
   }
 }
 @Override
 protected void doRun() {
   Listener listener;
   while (!isUnschedule() && (listener = queue.poll()) != null) {
     if (!listener.isExplicitClosed() && listener.hasHostFail()) {
       if (listener.canRetryFailLoop()) {
         try {
           SearchFilter filter = listener.getFilterForFailedHost();
           filter.setFailoverLoop(true);
           listener.reconnectFailedConnection(filter);
           // reconnection done !
         } catch (Exception e) {
           // FailoverLoop search connection failed
           queue.add(listener);
         }
       }
     }
   }
 }
  /**
   * Loop to connect failed hosts.
   *
   * @param searchFilter search parameters.
   * @throws QueryException if there is any error during reconnection
   */
  @Override
  public void reconnectFailedConnection(SearchFilter searchFilter) throws QueryException {
    proxy.lock.lock();
    try {
      if (!searchFilter.isInitialConnection() && (isExplicitClosed() || !isMasterHostFail())) {
        return;
      }

      currentConnectionAttempts.incrementAndGet();
      resetOldsBlackListHosts();

      List<HostAddress> loopAddress = new LinkedList<>(urlParser.getHostAddresses());
      if (HaMode.FAILOVER.equals(mode)) {
        // put the list in the following order
        // - random order not connected host
        // - random order blacklist host
        // - random order connected host
        loopAddress.removeAll(getBlacklistKeys());
        Collections.shuffle(loopAddress);
        List<HostAddress> blacklistShuffle = new LinkedList<>(getBlacklistKeys());
        Collections.shuffle(blacklistShuffle);
        loopAddress.addAll(blacklistShuffle);
      } else {
        // order in sequence
        loopAddress.removeAll(getBlacklistKeys());
        loopAddress.addAll(getBlacklistKeys());
      }

      // put connected at end
      if (currentProtocol != null && !isMasterHostFail()) {
        loopAddress.remove(currentProtocol.getHostAddress());
        // loopAddress.add(currentProtocol.getHostAddress());
      }

      MasterProtocol.loop(this, loopAddress, searchFilter);
      // close loop if all connection are retrieved
      if (!isMasterHostFail()) {
        FailoverLoop.removeListener(this);
      }

      // if no error, reset failover variables
      resetMasterFailoverData();
    } finally {
      proxy.lock.unlock();
    }
  }