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