View Javadoc

1   /*
2    * $Id: ExpiryMonitor.java 7963 2007-08-21 08:53:15Z dirk.olmes $
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.umo.lifecycle.Disposable;
14  
15  import java.util.Iterator;
16  import java.util.Map;
17  import java.util.Timer;
18  import java.util.TimerTask;
19  
20  import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
21  import org.apache.commons.logging.Log;
22  import org.apache.commons.logging.LogFactory;
23  
24  /**
25   * <code>ExpiryMonitor</code> can monitor objects beased on an expiry time and can
26   * invoke a callback method once the object time has expired. If the object does
27   * expire it is removed from this monitor.
28   */
29  
30  // TODO we should probably rewrite this with ScheduledExecutor for stability IF we
31  // need it; right now this class is unused
32  
33  public class ExpiryMonitor extends TimerTask implements Disposable
34  {
35      /**
36       * logger used by this class
37       */
38      protected static final Log logger = LogFactory.getLog(ExpiryMonitor.class);
39  
40      private Timer timer;
41      private Map monitors;
42  
43      public ExpiryMonitor()
44      {
45          this(1000);
46      }
47  
48      public ExpiryMonitor(long monitorFrequency)
49      {
50  
51          timer = new Timer(true);
52          timer.schedule(this, monitorFrequency, monitorFrequency);
53          monitors = new ConcurrentHashMap();
54      }
55  
56      /**
57       * Adds an expirable object to monitor. If the Object is already being monitored
58       * it will be reset and the millisecond timeout will be ignored
59       * 
60       * @param milliseconds
61       * @param expirable
62       */
63      public void addExpirable(long milliseconds, Expirable expirable)
64      {
65          if (isRegistered(expirable))
66          {
67              resetExpirable(expirable);
68          }
69          else
70          {
71              if (logger.isDebugEnabled())
72              {
73                  logger.debug("Adding new expirable: " + expirable);
74              }
75              monitors.put(expirable, new ExpirableHolder(milliseconds, expirable));
76          }
77      }
78  
79      public boolean isRegistered(Expirable expirable)
80      {
81          return (monitors.get(expirable) != null);
82      }
83  
84      public void removeExpirable(Expirable expirable)
85      {
86          if (logger.isDebugEnabled())
87          {
88              logger.debug("Removing expirable: " + expirable);
89          }
90          monitors.remove(expirable);
91      }
92  
93      public void resetExpirable(Expirable expirable)
94      {
95          ExpirableHolder eh = (ExpirableHolder) monitors.get(expirable);
96          if (eh != null)
97          {
98              eh.reset();
99              if (logger.isDebugEnabled())
100             {
101                 logger.debug("Reset expirable: " + expirable);
102             }
103         }
104     }
105 
106     /**
107      * The action to be performed by this timer task.
108      */
109     public void run()
110     {
111         ExpirableHolder holder;
112         for (Iterator iterator = monitors.values().iterator(); iterator.hasNext();)
113         {
114             holder = (ExpirableHolder) iterator.next();
115             if (holder.isExpired())
116             {
117                 removeExpirable(holder.getExpirable());
118                 holder.getExpirable().expired();
119             }
120         }
121     }
122 
123     public void dispose()
124     {
125         logger.info("disposing monitor");
126         timer.cancel();
127         ExpirableHolder holder;
128         for (Iterator iterator = monitors.values().iterator(); iterator.hasNext();)
129         {
130             holder = (ExpirableHolder) iterator.next();
131             removeExpirable(holder.getExpirable());
132             try
133             {
134                 holder.getExpirable().expired();
135             }
136             catch (Exception e)
137             {
138                 // TODO MULE-863: What should we really do?
139                 logger.debug(e.getMessage());
140             }
141         }
142     }
143 
144     private class ExpirableHolder
145     {
146 
147         private long milliseconds;
148         private Expirable expirable;
149         private long created;
150 
151         public ExpirableHolder(long milliseconds, Expirable expirable)
152         {
153             this.milliseconds = milliseconds;
154             this.expirable = expirable;
155             created = System.currentTimeMillis();
156         }
157 
158         public long getMilliseconds()
159         {
160             return milliseconds;
161         }
162 
163         public Expirable getExpirable()
164         {
165             return expirable;
166         }
167 
168         public boolean isExpired()
169         {
170             return (System.currentTimeMillis() - milliseconds) > created;
171         }
172 
173         public void reset()
174         {
175             created = System.currentTimeMillis();
176         }
177     }
178 }