protected void connectAndRestore()

in commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/remote/RemoteCacheNoWaitFacade.java [132:274]


    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(false);

        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. "
                        + "Failover index = {0} Will now try to reconnect to "
                        + "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. "
                            + "Cache failover runner is going to sleep for "
                            + "{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." );
            }
        }
    }