Coverage Report - org.mule.util.monitor.ExpiryMonitor
 
Classes in this File Line Coverage Branch Coverage Complexity
ExpiryMonitor
58%
32/55
55%
12/22
1.8
ExpiryMonitor$ExpirableHolder
90%
9/10
100%
2/2
1.8
 
 1  
 /*
 2  
  * $Id: ExpiryMonitor.java 12269 2008-07-10 04:19:03Z dfeist $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.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 edu.emory.mathcs.backport.java.util.concurrent.helpers.Utils;
 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  2
     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  
     public ExpiryMonitor(String name)
 48  
     {
 49  0
         this(name, 1000);
 50  0
     }
 51  
 
 52  
     public ExpiryMonitor(String name, int monitorFrequency)
 53  8
     {
 54  8
         this.name = name;
 55  8
         this.monitorFrequency = monitorFrequency;
 56  8
         init();
 57  8
     }
 58  
 
 59  
     public ExpiryMonitor(String name, int monitorFrequency, ScheduledThreadPoolExecutor scheduler)
 60  0
     {
 61  0
         this.name = name;
 62  0
         this.monitorFrequency = monitorFrequency;
 63  0
         this.scheduler = scheduler;
 64  0
         init();
 65  0
     }
 66  
 
 67  
     protected void init()
 68  
     {
 69  8
         if (monitorFrequency <= 0)
 70  
         {
 71  0
             throw new IllegalArgumentException(CoreMessages.propertyHasInvalidValue("monitorFrequency",
 72  
                     new Integer(monitorFrequency)).toString());
 73  
         }
 74  8
         monitors = new ConcurrentHashMap();
 75  8
         if (scheduler == null)
 76  
         {
 77  8
             this.scheduler = new ScheduledThreadPoolExecutor(1);
 78  8
             scheduler.setThreadFactory(new DaemonThreadFactory(name + "-Monitor"));
 79  8
             scheduler.scheduleWithFixedDelay(this, 0, monitorFrequency,
 80  
                     TimeUnit.MILLISECONDS);
 81  
         }
 82  8
     }
 83  
 
 84  
     /**
 85  
      * Adds an expirable object to monitor. If the Object is already being monitored
 86  
      * it will be reset and the millisecond timeout will be ignored
 87  
      *
 88  
      * @param value     the expiry value
 89  
      * @param timeUnit  The time unit of the Expiry value
 90  
      * @param expirable the objec that will expire
 91  
      */
 92  
     public void addExpirable(long value, TimeUnit timeUnit, Expirable expirable)
 93  
     {
 94  8
         if (isRegistered(expirable))
 95  
         {
 96  0
             resetExpirable(expirable);
 97  
         }
 98  
         else
 99  
         {
 100  8
             if (logger.isDebugEnabled())
 101  
             {
 102  0
                 logger.debug("Adding new expirable: " + expirable);
 103  
             }
 104  8
             monitors.put(expirable, new ExpirableHolder(timeUnit.toNanos(value), expirable));
 105  
         }
 106  8
     }
 107  
 
 108  
     public boolean isRegistered(Expirable expirable)
 109  
     {
 110  16
         return (monitors.get(expirable) != null);
 111  
     }
 112  
 
 113  
     public void removeExpirable(Expirable expirable)
 114  
     {
 115  8
         if (logger.isDebugEnabled())
 116  
         {
 117  0
             logger.debug("Removing expirable: " + expirable);
 118  
         }
 119  8
         monitors.remove(expirable);
 120  8
     }
 121  
 
 122  
     public void resetExpirable(Expirable expirable)
 123  
     {
 124  2
         ExpirableHolder eh = (ExpirableHolder) monitors.get(expirable);
 125  2
         if (eh != null)
 126  
         {
 127  2
             eh.reset();
 128  2
             if (logger.isDebugEnabled())
 129  
             {
 130  0
                 logger.debug("Reset expirable: " + expirable);
 131  
             }
 132  
         }
 133  2
     }
 134  
 
 135  
     /**
 136  
      * The action to be performed by this timer task.
 137  
      */
 138  
     public void run()
 139  
     {
 140  
         ExpirableHolder holder;
 141  3681
         for (Iterator iterator = monitors.values().iterator(); iterator.hasNext();)
 142  
         {
 143  49
             holder = (ExpirableHolder) iterator.next();
 144  49
             if (holder.isExpired())
 145  
             {
 146  6
                 removeExpirable(holder.getExpirable());
 147  6
                 holder.getExpirable().expired();
 148  
             }
 149  
         }
 150  3681
     }
 151  
 
 152  
     public void dispose()
 153  
     {
 154  0
         logger.info("disposing monitor");
 155  0
         scheduler.shutdown();
 156  
         ExpirableHolder holder;
 157  0
         for (Iterator iterator = monitors.values().iterator(); iterator.hasNext();)
 158  
         {
 159  0
             holder = (ExpirableHolder) iterator.next();
 160  0
             removeExpirable(holder.getExpirable());
 161  
             try
 162  
             {
 163  0
                 holder.getExpirable().expired();
 164  
             }
 165  0
             catch (Exception e)
 166  
             {
 167  
                 // TODO MULE-863: What should we really do?
 168  0
                 logger.debug(e.getMessage());
 169  0
             }
 170  
         }
 171  0
     }
 172  
 
 173  
     private static class ExpirableHolder
 174  
     {
 175  
 
 176  
         private long nanoseconds;
 177  
         private Expirable expirable;
 178  
         private long created;
 179  
 
 180  
         public ExpirableHolder(long nanoseconds, Expirable expirable)
 181  8
         {
 182  8
             this.nanoseconds = nanoseconds;
 183  8
             this.expirable = expirable;
 184  8
             created = Utils.nanoTime();
 185  8
         }
 186  
 
 187  
         public long getNanoSeconds()
 188  
         {
 189  0
             return nanoseconds;
 190  
         }
 191  
 
 192  
         public Expirable getExpirable()
 193  
         {
 194  12
             return expirable;
 195  
         }
 196  
 
 197  
         public boolean isExpired()
 198  
         {
 199  49
             return (Utils.nanoTime() - nanoseconds) > created;
 200  
         }
 201  
 
 202  
         public void reset()
 203  
         {
 204  2
             created = Utils.nanoTime();
 205  2
         }
 206  
     }
 207  
 }