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