Coverage report

  %line %branch
org.apache.jcs.auxiliary.lateral.LateralCacheMonitor
53% 
83% 

 1  
 package org.apache.jcs.auxiliary.lateral;
 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.commons.logging.Log;
 25  
 import org.apache.commons.logging.LogFactory;
 26  
 import org.apache.jcs.auxiliary.lateral.behavior.ILateralCacheManager;
 27  
 import org.apache.jcs.engine.CacheConstants;
 28  
 
 29  
 /**
 30  
  * Used to monitor and repair any failed connection for the lateral 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. Upon the notification of a
 33  
  * connection error, the monitor changes to operate in a time driven mode. That
 34  
  * is, it attempts to recover the connections on a periodic basis. When all
 35  
  * failed connections are restored, it changes back to the failure driven mode.
 36  
  *
 37  
  */
 38  
 public class LateralCacheMonitor
 39  
     implements Runnable
 40  
 {
 41  28
     private final static Log log = LogFactory.getLog( LateralCacheMonitor.class );
 42  
 
 43  14
     private static long idlePeriod = 20 * 1000;
 44  
 
 45  
     // minimum 20 seconds.
 46  
     //private static long idlePeriod = 3*1000; // for debugging.
 47  
 
 48  
     // Must make sure LateralCacheMonitor is started before any lateral error
 49  
     // can be detected!
 50  14
     private boolean alright = true;
 51  
 
 52  
     private final static int ERROR = 1;
 53  
 
 54  14
     private static int mode = ERROR;
 55  
 
 56  
     private ILateralCacheManager manager;
 57  
 
 58  
     /**
 59  
      * Configures the idle period between repairs.
 60  
      *
 61  
      * @param idlePeriod
 62  
      *            The new idlePeriod value
 63  
      */
 64  
     public static void setIdlePeriod( long idlePeriod )
 65  
     {
 66  0
         if ( idlePeriod > LateralCacheMonitor.idlePeriod )
 67  
         {
 68  0
             LateralCacheMonitor.idlePeriod = idlePeriod;
 69  
         }
 70  0
     }
 71  
 
 72  
     /**
 73  
      * Allows close classes, ie testers to set the idle period to something
 74  
      * testable.
 75  
      *
 76  
      * @param idlePeriod
 77  
      */
 78  
     protected static void forceShortIdlePeriod( long idlePeriod )
 79  
     {
 80  0
         LateralCacheMonitor.idlePeriod = idlePeriod;
 81  0
     }
 82  
 
 83  
     /** Constructor for the LateralCacheMonitor object
 84  
      * <p>
 85  
      * It's the clients responsibility to decide how many
 86  
      * of these there will be.
 87  
      *
 88  
      * @param manager
 89  
      */
 90  
     public LateralCacheMonitor( ILateralCacheManager manager )
 91  14
     {
 92  14
         this.manager = manager;
 93  14
     }
 94  
 
 95  
     /**
 96  
      * Notifies the cache monitor that an error occurred, and kicks off the
 97  
      * error recovery process.
 98  
      */
 99  
     public void notifyError()
 100  
     {
 101  14
         bad();
 102  14
         synchronized ( this )
 103  
         {
 104  14
             notify();
 105  14
         }
 106  14
     }
 107  
 
 108  
     /**
 109  
      * Main processing method for the LateralCacheMonitor object
 110  
      */
 111  
     public void run()
 112  
     {
 113  
         do
 114  
         {
 115  14
             if ( mode == ERROR )
 116  
             {
 117  14
                 if ( log.isDebugEnabled() )
 118  
                 {
 119  0
                     if ( alright )
 120  
                     {
 121  0
                         log.debug( "ERROR DRIVEN MODE: alright = " + alright
 122  
                             + ", connection monitor will wait for an error." );
 123  0
                     }
 124  
                     else
 125  
                     {
 126  0
                         log.debug( "ERROR DRIVEN MODE: alright = " + alright + " connection monitor running." );
 127  
                     }
 128  
                 }
 129  
 
 130  14
                 if ( alright )
 131  
                 {
 132  0
                     synchronized ( this )
 133  
                     {
 134  0
                         if ( alright )
 135  
                         {
 136  
                             // Failure driven mode.
 137  
                             try
 138  
                             {
 139  0
                                 wait();
 140  
                                 // wake up only if there is an error.
 141  
                             }
 142  0
                             catch ( InterruptedException ignore )
 143  
                             {
 144  
                                 //no op, this is expected
 145  0
                             }
 146  
                         }
 147  0
                     }
 148  0
                 }
 149  
             }
 150  
             else
 151  
             {
 152  0
                 log.debug( "TIME DRIVEN MODE: connection monitor will sleep for " + idlePeriod + " after this run." );
 153  
                 // Time driven mode: sleep between each round of recovery
 154  
                 // attempt.
 155  
                 // will need to test not just check status
 156  
             }
 157  
 
 158  
             // The "alright" flag must be false here.
 159  
             // Simply presume we can fix all the errors until proven otherwise.
 160  14
             synchronized ( this )
 161  
             {
 162  14
                 alright = true;
 163  14
             }
 164  
 
 165  14
             if ( log.isDebugEnabled() )
 166  
             {
 167  0
                 log.debug( "Cache monitor running." );
 168  
             }
 169  
 
 170  
             // Monitor each LateralCacheManager instance one after the other.
 171  
             // Each LateralCacheManager corresponds to one lateral connection.
 172  14
             log.info( "LateralCacheManager.instances.size() = " + manager.getInstances().size() );
 173  
             //for
 174  14
             int cnt = 0;
 175  14
             Iterator itr = manager.getInstances().values().iterator();
 176  28
             while ( itr.hasNext() )
 177  
             {
 178  14
                 cnt++;
 179  14
                 ILateralCacheManager mgr = (ILateralCacheManager) itr.next();
 180  
                 try
 181  
                 {
 182  
                     // If any cache is in error, it strongly suggests all caches
 183  
                     // managed by the
 184  
                     // same LateralCacheManager instance are in error. So we fix
 185  
                     // them once and for all.
 186  
                     //for
 187  
                     //log.info( "\n " + cnt + "- mgr.lca.getTcpServer() = " + mgr.lca.getTcpServer() + " mgr = " + mgr );
 188  14
                     log.info( "\n " + cnt + "- mgr.getCaches().size() = " + mgr.getCaches().size() );
 189  
 
 190  14
                     if ( mgr.getCaches().size() == 0 )
 191  
                     {
 192  
                         // there is probably a problem.
 193  
                         // monitor may be running when we just started up and
 194  
                         // there
 195  
                         // is not a cache yet.
 196  
                         // if this is error driven mode, mark as bad,
 197  
                         // otherwise we will come back around argain.
 198  14
                         if ( mode == ERROR )
 199  
                         {
 200  14
                             bad();
 201  
                         }
 202  
                     }
 203  
 
 204  14
                     Iterator itr2 = mgr.getCaches().values().iterator();
 205  
 
 206  14
                     while ( itr2.hasNext() )
 207  
                     {
 208  0
                         LateralCacheNoWait c = (LateralCacheNoWait) itr2.next();
 209  0
                         if ( c.getStatus() == CacheConstants.STATUS_ERROR )
 210  
                         {
 211  0
                             log.info( "found LateralCacheNoWait in error, " + c.toString() );
 212  
 
 213  0
                             LateralCacheRestore repairer = new LateralCacheRestore( mgr );
 214  
                             // If we can't fix them, just skip and re-try in the
 215  
                             // next round.
 216  0
                             if ( repairer.canFix() )
 217  
                             {
 218  0
                                 repairer.fix();
 219  0
                             }
 220  
                             else
 221  
                             {
 222  0
                                 bad();
 223  
                             }
 224  
                             //break;
 225  0
                         }
 226  
                         else
 227  
                         {
 228  0
                             log.info( "Lateral Cache No Wait not in error" );
 229  
                         }
 230  0
                     }
 231  
                 }
 232  0
                 catch ( Exception ex )
 233  
                 {
 234  0
                     bad();
 235  
                     // Problem encountered in fixing the caches managed by a
 236  
                     // LateralCacheManager instance.
 237  
                     // Soldier on to the next LateralCacheManager instance.
 238  0
                     log.error( "Problem encountered in fixing the caches", ex );
 239  14
                 }
 240  14
             }
 241  
 
 242  
             try
 243  
             {
 244  
                 // don't want to sleep after waking from an error
 245  
                 // run immediately and sleep here.
 246  14
                 if ( log.isDebugEnabled() )
 247  
                 {
 248  0
                     log.debug( "Lateral cache monitor sleeping for " + idlePeriod + " between runs." );
 249  
                 }
 250  
 
 251  14
                 Thread.sleep( idlePeriod );
 252  
             }
 253  0
             catch ( InterruptedException ex )
 254  
             {
 255  
                 // ignore;
 256  0
             }
 257  
         }
 258  0
         while ( true );
 259  
     }
 260  
 
 261  
     /**
 262  
      * Sets the "alright" flag to false in a critial section.
 263  
      */
 264  
     private void bad()
 265  
     {
 266  28
         if ( alright )
 267  
         {
 268  28
             synchronized ( this )
 269  
             {
 270  28
                 alright = false;
 271  28
             }
 272  
         }
 273  28
     }
 274  
 }

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