Coverage report

  %line %branch
org.apache.jcs.auxiliary.remote.RemoteCacheMonitor
25% 
64% 

 1  
 package org.apache.jcs.auxiliary.remote;
 2  
 
 3  
 /*
 4  
  * Licensed to the Apache Software Foundation (ASF) under one
 5  
  * or more contributor license agreements.  See the NOTICE file
 6  
  * distributed with this work for additional information
 7  
  * regarding copyright ownership.  The ASF licenses this file
 8  
  * to you under the Apache License, Version 2.0 (the
 9  
  * "License"); you may not use this file except in compliance
 10  
  * with the License.  You may obtain a copy of the License at
 11  
  *
 12  
  *   http://www.apache.org/licenses/LICENSE-2.0
 13  
  *
 14  
  * Unless required by applicable law or agreed to in writing,
 15  
  * software distributed under the License is distributed on an
 16  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 17  
  * KIND, either express or implied.  See the License for the
 18  
  * specific language governing permissions and limitations
 19  
  * under the License.
 20  
  */
 21  
 
 22  
 import java.util.Iterator;
 23  
 
 24  
 import org.apache.jcs.engine.CacheConstants;
 25  
 
 26  
 import org.apache.commons.logging.Log;
 27  
 import org.apache.commons.logging.LogFactory;
 28  
 
 29  
 /**
 30  
  * Used to monitor and repair any failed connection for the remote cache
 31  
  * service. By default the monitor operates in a failure driven mode. That is,
 32  
  * it goes into a wait state until there is an error. TODO consider moving this
 33  
  * into an active monitoring mode. Upon the notification of a connection error,
 34  
  * the monitor changes to operate in a time driven mode. That is, it attempts to
 35  
  * recover the connections on a periodic basis. When all failed connections are
 36  
  * restored, it changes back to the failure driven mode.
 37  
  *
 38  
  */
 39  
 public class RemoteCacheMonitor
 40  
     implements Runnable
 41  
 {
 42  
     /** The logger */
 43  14
     private final static Log log = LogFactory.getLog( RemoteCacheMonitor.class );
 44  
 
 45  
     /** The remote cache that we are monitoring */
 46  
     private static RemoteCacheMonitor instance;
 47  
 
 48  
     /** Time between checks */
 49  7
     private static long idlePeriod = 30 * 1000;
 50  
 
 51  
     // minimum 30 seconds.
 52  
     //private static long idlePeriod = 3*1000; // for debugging.
 53  
 
 54  
     /** Must make sure RemoteCacheMonitor is started before any remote error can
 55  
     * be detected! */
 56  7
     private boolean alright = true;
 57  
 
 58  
     /** Time driven mode */
 59  
     final static int TIME = 0;
 60  
 
 61  
     /** Error driven mode -- only check on health if there is an error */
 62  
     final static int ERROR = 1;
 63  
 
 64  
     /** The mode to use */
 65  7
     static int mode = ERROR;
 66  
 
 67  
     /**
 68  
      * Configures the idle period between repairs.
 69  
      *
 70  
      * @param idlePeriod
 71  
      *            The new idlePeriod value
 72  
      */
 73  
     public static void setIdlePeriod( long idlePeriod )
 74  
     {
 75  0
         if ( idlePeriod > RemoteCacheMonitor.idlePeriod )
 76  
         {
 77  0
             RemoteCacheMonitor.idlePeriod = idlePeriod;
 78  
         }
 79  0
     }
 80  
 
 81  
     /** Constructor for the RemoteCacheMonitor object */
 82  
     private RemoteCacheMonitor()
 83  
     {
 84  7
         super();
 85  7
     }
 86  
 
 87  
     /**
 88  
      * Returns the singleton instance;
 89  
      *
 90  
      * @return The instance value
 91  
      */
 92  
     static RemoteCacheMonitor getInstance()
 93  
     {
 94  7
         synchronized ( RemoteCacheMonitor.class )
 95  
         {
 96  7
             if ( instance == null )
 97  
             {
 98  7
                 return instance = new RemoteCacheMonitor();
 99  
             }
 100  0
         }
 101  0
         return instance;
 102  
     }
 103  
 
 104  
     /**
 105  
      * Notifies the cache monitor that an error occurred, and kicks off the
 106  
      * error recovery process.
 107  
      */
 108  
     public void notifyError()
 109  
     {
 110  0
         log.debug( "Notified of an error." );
 111  0
         bad();
 112  0
         synchronized ( this )
 113  
         {
 114  0
             notify();
 115  0
         }
 116  0
     }
 117  
 
 118  
     // Run forever.
 119  
 
 120  
     // Avoid the use of any synchronization in the process of monitoring for
 121  
     // performance reason.
 122  
     // If exception is thrown owing to synchronization,
 123  
     // just skip the monitoring until the next round.
 124  
     /** Main processing method for the RemoteCacheMonitor object */
 125  
     public void run()
 126  
     {
 127  7
         log.debug( "Monitoring daemon started" );
 128  
         do
 129  
         {
 130  7
             if ( mode == ERROR )
 131  
             {
 132  7
                 synchronized ( this )
 133  
                 {
 134  7
                     if ( alright )
 135  
                     {
 136  
                         // make this configurable, comment out wait to enter
 137  
                         // time driven mode
 138  
                         // Failure driven mode.
 139  
                         try
 140  
                         {
 141  7
                             if ( log.isDebugEnabled() )
 142  
                             {
 143  0
                                 log.debug( "FAILURE DRIVEN MODE: cache monitor waiting for error" );
 144  
                             }
 145  7
                             wait();
 146  
                             // wake up only if there is an error.
 147  
                         }
 148  0
                         catch ( InterruptedException ignore )
 149  
                         {
 150  
                             // swallow
 151  0
                         }
 152  
                     }
 153  0
                 }
 154  0
             }
 155  
             else
 156  
             {
 157  0
                 if ( log.isDebugEnabled() )
 158  
                 {
 159  0
                     log.debug( "TIME DRIVEN MODE: cache monitor sleeping for " + idlePeriod );
 160  
                 }
 161  
                 // Time driven mode: sleep between each round of recovery
 162  
                 // attempt.
 163  
                 // will need to test not just check status
 164  
             }
 165  
 
 166  
             try
 167  
             {
 168  0
                 Thread.sleep( idlePeriod );
 169  
             }
 170  0
             catch ( InterruptedException ex )
 171  
             {
 172  
                 // ignore;
 173  0
             }
 174  
 
 175  
             // The "alright" flag must be false here.
 176  
             // Simply presume we can fix all the errors until proven otherwise.
 177  0
             synchronized ( this )
 178  
             {
 179  0
                 alright = true;
 180  0
             }
 181  
             //p("cache monitor running.");
 182  
             // Monitor each RemoteCacheManager instance one after the other.
 183  
             // Each RemoteCacheManager corresponds to one remote connection.
 184  0
             for ( Iterator itr = RemoteCacheManager.instances.values().iterator(); itr.hasNext(); )
 185  
             {
 186  0
                 RemoteCacheManager mgr = (RemoteCacheManager) itr.next();
 187  
                 try
 188  
                 {
 189  
                     // If any cache is in error, it strongly suggests all caches
 190  
                     // managed by the
 191  
                     // same RmicCacheManager instance are in error. So we fix
 192  
                     // them once and for all.
 193  0
                     for ( Iterator itr2 = mgr.caches.values().iterator(); itr2.hasNext(); )
 194  
                     {
 195  0
                         if ( itr2.hasNext() )
 196  
                         {
 197  0
                             RemoteCacheNoWait c = (RemoteCacheNoWait) itr2.next();
 198  0
                             if ( c.getStatus() == CacheConstants.STATUS_ERROR )
 199  
                             {
 200  0
                                 RemoteCacheRestore repairer = new RemoteCacheRestore( mgr );
 201  
                                 // If we can't fix them, just skip and re-try in
 202  
                                 // the next round.
 203  0
                                 if ( repairer.canFix() )
 204  
                                 {
 205  0
                                     repairer.fix();
 206  0
                                 }
 207  
                                 else
 208  
                                 {
 209  0
                                     bad();
 210  
                                 }
 211  0
                                 break;
 212  
                             }
 213  0
                         }
 214  
                     }
 215  
                 }
 216  0
                 catch ( Exception ex )
 217  
                 {
 218  0
                     bad();
 219  
                     // Problem encountered in fixing the caches managed by a
 220  
                     // RemoteCacheManager instance.
 221  
                     // Soldier on to the next RemoteCacheManager instance.
 222  0
                     log.error( ex );
 223  0
                 }
 224  0
             }
 225  
         }
 226  0
         while ( true );
 227  
     }
 228  
 
 229  
     /** Sets the "alright" flag to false in a critial section. */
 230  
     private synchronized void bad()
 231  
     {
 232  0
         alright = false;
 233  0
     }
 234  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.