Coverage Report - org.mule.util.monitor.ExpiryMonitor
 
Classes in this File Line Coverage Branch Coverage Complexity
ExpiryMonitor
0%
0/61
0%
0/22
1.75
ExpiryMonitor$ExpirableHolder
0%
0/10
0%
0/2
1.75
 
 1  
 /*
 2  
  * $Id: ExpiryMonitor.java 19191 2010-08-25 21:05:23Z tcarlson $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
 5  
  *
 6  
  * The software in this package is published under the terms of the CPAL v1.0
 7  
  * license, a copy of which has been included with this distribution in the
 8  
  * LICENSE.txt file.
 9  
  */
 10  
 
 11  
 package org.mule.util.monitor;
 12  
 
 13  
 import org.mule.api.lifecycle.Disposable;
 14  
 import org.mule.config.i18n.CoreMessages;
 15  
 import org.mule.util.concurrent.DaemonThreadFactory;
 16  
 
 17  
 import java.util.Iterator;
 18  
 import java.util.Map;
 19  
 
 20  
 import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
 21  
 import edu.emory.mathcs.backport.java.util.concurrent.ScheduledThreadPoolExecutor;
 22  
 import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
 23  
 
 24  
 import org.apache.commons.logging.Log;
 25  
 import org.apache.commons.logging.LogFactory;
 26  
 
 27  
 /**
 28  
  * <code>ExpiryMonitor</code> can monitor objects beased on an expiry time and can
 29  
  * invoke a callback method once the object time has expired. If the object does
 30  
  * expire it is removed from this monitor.
 31  
  */
 32  
 public class ExpiryMonitor implements Runnable, Disposable
 33  
 {
 34  
     /**
 35  
      * logger used by this class
 36  
      */
 37  0
     protected static final Log logger = LogFactory.getLog(ExpiryMonitor.class);
 38  
 
 39  
     protected ScheduledThreadPoolExecutor scheduler;
 40  
 
 41  
     private Map monitors;
 42  
 
 43  
     private int monitorFrequency;
 44  
 
 45  
     private String name;
 46  
     
 47  
     private ClassLoader contextClassLoader;
 48  
 
 49  
     public ExpiryMonitor(String name)
 50  
     {
 51  0
         this(name, 1000);
 52  0
     }
 53  
 
 54  
     public ExpiryMonitor(String name, int monitorFrequency)
 55  0
     {
 56  0
         this.name = name;
 57  0
         this.monitorFrequency = monitorFrequency;
 58  0
         init();
 59  0
     }
 60  
 
 61  
     public ExpiryMonitor(String name, int monitorFrequency, ClassLoader contextClassLoader)
 62  0
     {
 63  0
         this.name = name;
 64  0
         this.monitorFrequency = monitorFrequency;
 65  0
         this.contextClassLoader = contextClassLoader;
 66  0
         init();
 67  0
     }
 68  
     
 69  
     public ExpiryMonitor(String name, int monitorFrequency, ScheduledThreadPoolExecutor scheduler)
 70  0
     {
 71  0
         this.name = name;
 72  0
         this.monitorFrequency = monitorFrequency;
 73  0
         this.scheduler = scheduler;
 74  0
         init();
 75  0
     }
 76  
 
 77  
     protected void init()
 78  
     {
 79  0
         if (monitorFrequency <= 0)
 80  
         {
 81  0
             throw new IllegalArgumentException(CoreMessages.propertyHasInvalidValue("monitorFrequency",
 82  
                     new Integer(monitorFrequency)).toString());
 83  
         }
 84  0
         monitors = new ConcurrentHashMap();
 85  0
         if (scheduler == null)
 86  
         {
 87  0
             this.scheduler = new ScheduledThreadPoolExecutor(1);
 88  0
             scheduler.setThreadFactory(new DaemonThreadFactory(name + "-Monitor", contextClassLoader));
 89  0
             scheduler.scheduleWithFixedDelay(this, 0, monitorFrequency,
 90  
                     TimeUnit.MILLISECONDS);
 91  
         }
 92  0
     }
 93  
 
 94  
     /**
 95  
      * Adds an expirable object to monitor. If the Object is already being monitored
 96  
      * it will be reset and the millisecond timeout will be ignored
 97  
      *
 98  
      * @param value     the expiry value
 99  
      * @param timeUnit  The time unit of the Expiry value
 100  
      * @param expirable the objec that will expire
 101  
      */
 102  
     public void addExpirable(long value, TimeUnit timeUnit, Expirable expirable)
 103  
     {
 104  0
         if (isRegistered(expirable))
 105  
         {
 106  0
             resetExpirable(expirable);
 107  
         }
 108  
         else
 109  
         {
 110  0
             if (logger.isDebugEnabled())
 111  
             {
 112  0
                 logger.debug("Adding new expirable: " + expirable);
 113  
             }
 114  0
             monitors.put(expirable, new ExpirableHolder(timeUnit.toNanos(value), expirable));
 115  
         }
 116  0
     }
 117  
 
 118  
     public boolean isRegistered(Expirable expirable)
 119  
     {
 120  0
         return (monitors.get(expirable) != null);
 121  
     }
 122  
 
 123  
     public void removeExpirable(Expirable expirable)
 124  
     {
 125  0
         if (logger.isDebugEnabled())
 126  
         {
 127  0
             logger.debug("Removing expirable: " + expirable);
 128  
         }
 129  0
         monitors.remove(expirable);
 130  0
     }
 131  
 
 132  
     public void resetExpirable(Expirable expirable)
 133  
     {
 134  0
         ExpirableHolder eh = (ExpirableHolder) monitors.get(expirable);
 135  0
         if (eh != null)
 136  
         {
 137  0
             eh.reset();
 138  0
             if (logger.isDebugEnabled())
 139  
             {
 140  0
                 logger.debug("Reset expirable: " + expirable);
 141  
             }
 142  
         }
 143  0
     }
 144  
 
 145  
     /**
 146  
      * The action to be performed by this timer task.
 147  
      */
 148  
     public void run()
 149  
     {
 150  
         ExpirableHolder holder;
 151  0
         for (Iterator iterator = monitors.values().iterator(); iterator.hasNext();)
 152  
         {
 153  0
             holder = (ExpirableHolder) iterator.next();
 154  0
             if (holder.isExpired())
 155  
             {
 156  0
                 removeExpirable(holder.getExpirable());
 157  0
                 holder.getExpirable().expired();
 158  
             }
 159  
         }
 160  0
     }
 161  
 
 162  
     public void dispose()
 163  
     {
 164  0
         logger.info("disposing monitor");
 165  0
         scheduler.shutdown();
 166  
         ExpirableHolder holder;
 167  0
         for (Iterator iterator = monitors.values().iterator(); iterator.hasNext();)
 168  
         {
 169  0
             holder = (ExpirableHolder) iterator.next();
 170  0
             removeExpirable(holder.getExpirable());
 171  
             try
 172  
             {
 173  0
                 holder.getExpirable().expired();
 174  
             }
 175  0
             catch (Exception e)
 176  
             {
 177  
                 // TODO MULE-863: What should we really do?
 178  0
                 logger.debug(e.getMessage());
 179  0
             }
 180  
         }
 181  0
     }
 182  
 
 183  
     private static class ExpirableHolder
 184  
     {
 185  
 
 186  
         private long nanoseconds;
 187  
         private Expirable expirable;
 188  
         private long created;
 189  
 
 190  
         public ExpirableHolder(long nanoseconds, Expirable expirable)
 191  0
         {
 192  0
             this.nanoseconds = nanoseconds;
 193  0
             this.expirable = expirable;
 194  0
             created = System.nanoTime();
 195  0
         }
 196  
 
 197  
         public long getNanoSeconds()
 198  
         {
 199  0
             return nanoseconds;
 200  
         }
 201  
 
 202  
         public Expirable getExpirable()
 203  
         {
 204  0
             return expirable;
 205  
         }
 206  
 
 207  
         public boolean isExpired()
 208  
         {
 209  0
             return (System.nanoTime() - nanoseconds) > created;
 210  
         }
 211  
 
 212  
         public void reset()
 213  
         {
 214  0
             created = System.nanoTime();
 215  0
         }
 216  
     }
 217  
 }