in commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/remote/RemoteCacheNoWaitFacade.java [99:243]
protected void connectAndRestore()
{
final IRemoteCacheAttributes rca0 = getAuxiliaryCacheAttributes();
// Each RemoteCacheManager corresponds to one remote connection.
final List<RemoteLocation> failovers = rca0.getFailovers();
// we should probably check to see if there are any failovers,
// even though the caller should have already.
if ( failovers == null )
{
log.warn( "Remote is misconfigured, failovers was null." );
return;
}
if ( failovers.size() == 1 )
{
// if there is only the primary, return out of this
log.info( "No failovers defined, exiting failover runner." );
return;
}
final AtomicBoolean allright = new AtomicBoolean();
do
{
log.info( "Remote cache FAILOVER RUNNING." );
// there is no active listener
if ( !allright.get() )
{
// Monitor each RemoteCacheManager instance one after the other.
final int fidx = rca0.getFailoverIndex();
log.debug( "fidx = {0} failovers.size = {1}", rca0::getFailoverIndex, failovers::size);
// If we don't check the primary, if it gets connected in the
// background,
// we will disconnect it only to put it right back
final ListIterator<RemoteLocation> i = failovers.listIterator(fidx); // + 1; // +1 skips the primary
log.debug( "starting at failover i = {0}", i );
// try them one at a time until successful
while (i.hasNext() && !allright.get())
{
final int failoverIndex = i.nextIndex();
final RemoteLocation server = i.next();
log.debug("Trying server [{0}] at failover index i = {1}", server, failoverIndex);
final RemoteCacheAttributes rca = (RemoteCacheAttributes) rca0.clone();
rca.setRemoteLocation(server);
final RemoteCacheManager rcm = cacheFactory.getManager( rca );
log.debug( "RemoteCacheAttributes for failover = {0}", rca );
if (rcm != null)
{
// add a listener if there are none, need to tell rca
// what number it is at
final ICache<K, V> ic = rcm.getCache( rca );
if ( ic.getStatus() == CacheStatus.ALIVE )
{
// may need to do this more gracefully
log.debug( "resetting no wait" );
restorePrimaryServer((RemoteCacheNoWait<K, V>) ic);
rca0.setFailoverIndex(failoverIndex);
log.debug("setting ALLRIGHT to true");
if (i.hasPrevious())
{
log.debug("Moving to Primary Recovery Mode, failover index = {0}", failoverIndex);
}
else
{
log.debug("No need to connect to failover, the primary server is back up.");
}
allright.set(true);
log.info( "CONNECTED to host = [{0}]", rca::getRemoteLocation);
}
}
}
}
// end if !allright
// get here if while index >0 and allright, meaning that we are
// connected to some backup server.
else
{
log.debug( "ALLRIGHT is true " );
log.info( """
Failover runner is in primary recovery mode.\s\
Failover index = {0} Will now try to reconnect to\s\
primary server.""", rca0::getFailoverIndex);
}
// Exit loop if in test mode
if (allright.get() && !attemptRestorePrimary)
{
break;
}
boolean primaryRestoredSuccessfully = false;
// if we are not connected to the primary, try.
if (rca0.getFailoverIndex() > 0)
{
primaryRestoredSuccessfully = restorePrimary();
log.debug( "Primary recovery success state = {0}",
primaryRestoredSuccessfully );
}
if (!primaryRestoredSuccessfully)
{
// Time driven mode: sleep between each round of recovery attempt.
try
{
log.warn( """
Failed to reconnect to primary server.\s\
Cache failover runner is going to sleep for\s\
{0} milliseconds.""", idlePeriod );
Thread.sleep( idlePeriod );
}
catch ( final InterruptedException ex )
{
// ignore;
}
}
// try to bring the listener back to the primary
}
while (rca0.getFailoverIndex() > 0 || !allright.get());
// continue if the primary is not restored or if things are not allright.
if ( log.isInfoEnabled() )
{
final int failoverIndex = rca0.getFailoverIndex();
log.info( "Exiting failover runner. Failover index = {0}", failoverIndex);
if ( failoverIndex <= 0 )
{
log.info( "Failover index is <= 0, meaning we are not connected to a failover server." );
}
else
{
log.info( "Failover index is > 0, meaning we are connected to a failover server." );
}
}
}