@Override
    public void run2() {
      try {
        initializedLatch.await();
        synchronized (lock) {
          if (isCancelled) {
            return;
          } else {
            redundancySatisfierTask = null;
          }
          if (pool.getPoolOrCacheCancelInProgress() != null) {
            /* wake up waiters so they can detect cancel */
            lock.notifyAll();
            return;
          }
        }
        Set<ServerLocation> excludedServers = queueConnections.getAllLocations();
        excludedServers.addAll(denyList.getBadServers());
        excludedServers.addAll(factory.getDenyList().getBadServers());
        recoverPrimary(excludedServers);
        recoverRedundancy(excludedServers, true);
      } catch (VirtualMachineError err) {
        SystemFailure.initiateFailure(err);
        // If this ever returns, rethrow the error. We're poisoned
        // now, so don't let this thread continue.
        throw err;
      } catch (CancelException e) {
        throw e;
      } catch (Throwable t) {
        // Whenever you catch Error or Throwable, you must also
        // catch VirtualMachineError (see above). However, there is
        // _still_ a possibility that you are dealing with a cascading
        // error condition, so you also need to check to see if the JVM
        // is still usable:
        SystemFailure.checkFailure();
        synchronized (lock) {
          if (t instanceof GemFireSecurityException) {
            queueConnections = queueConnections
                .setPrimaryDiscoveryFailed((GemFireSecurityException) t);
          } else {
            queueConnections = queueConnections.setPrimaryDiscoveryFailed(null);
          }
          lock.notifyAll();
          pool.getCancelCriterion().checkCancelInProgress(t);
          logError("Error in redundancy satisfier", t);
        }
      }

      scheduleRedundancySatisfierIfNeeded(redundancyRetryInterval);
    }
Asynchronous task which tries to reestablish a primary connection and satisfy redundant
requirements.

This task should only be running in a single thread at a time. This task is the only way that
new queue servers will be added, and the only way that a backup server can transistion to a
primary server.
geode-core/src/main/java/org/apache/geode/cache/client/internal/QueueManagerImpl.java