1
2
3
4
5
6
7
8
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
29
30
31
32 public class ExpiryMonitor implements Runnable, Disposable
33 {
34
35
36
37 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 this(name, 1000);
50 }
51
52 public ExpiryMonitor(String name, int monitorFrequency)
53 {
54 this.name = name;
55 this.monitorFrequency = monitorFrequency;
56 init();
57 }
58
59 public ExpiryMonitor(String name, int monitorFrequency, ScheduledThreadPoolExecutor scheduler)
60 {
61 this.name = name;
62 this.monitorFrequency = monitorFrequency;
63 this.scheduler = scheduler;
64 init();
65 }
66
67 protected void init()
68 {
69 if (monitorFrequency <= 0)
70 {
71 throw new IllegalArgumentException(CoreMessages.propertyHasInvalidValue("monitorFrequency",
72 new Integer(monitorFrequency)).toString());
73 }
74 monitors = new ConcurrentHashMap();
75 if (scheduler == null)
76 {
77 this.scheduler = new ScheduledThreadPoolExecutor(1);
78 scheduler.setThreadFactory(new DaemonThreadFactory(name + "-Monitor"));
79 scheduler.scheduleWithFixedDelay(this, 0, monitorFrequency,
80 TimeUnit.MILLISECONDS);
81 }
82 }
83
84
85
86
87
88
89
90
91
92 public void addExpirable(long value, TimeUnit timeUnit, Expirable expirable)
93 {
94 if (isRegistered(expirable))
95 {
96 resetExpirable(expirable);
97 }
98 else
99 {
100 if (logger.isDebugEnabled())
101 {
102 logger.debug("Adding new expirable: " + expirable);
103 }
104 monitors.put(expirable, new ExpirableHolder(timeUnit.toNanos(value), expirable));
105 }
106 }
107
108 public boolean isRegistered(Expirable expirable)
109 {
110 return (monitors.get(expirable) != null);
111 }
112
113 public void removeExpirable(Expirable expirable)
114 {
115 if (logger.isDebugEnabled())
116 {
117 logger.debug("Removing expirable: " + expirable);
118 }
119 monitors.remove(expirable);
120 }
121
122 public void resetExpirable(Expirable expirable)
123 {
124 ExpirableHolder eh = (ExpirableHolder) monitors.get(expirable);
125 if (eh != null)
126 {
127 eh.reset();
128 if (logger.isDebugEnabled())
129 {
130 logger.debug("Reset expirable: " + expirable);
131 }
132 }
133 }
134
135
136
137
138 public void run()
139 {
140 ExpirableHolder holder;
141 for (Iterator iterator = monitors.values().iterator(); iterator.hasNext();)
142 {
143 holder = (ExpirableHolder) iterator.next();
144 if (holder.isExpired())
145 {
146 removeExpirable(holder.getExpirable());
147 holder.getExpirable().expired();
148 }
149 }
150 }
151
152 public void dispose()
153 {
154 logger.info("disposing monitor");
155 scheduler.shutdown();
156 ExpirableHolder holder;
157 for (Iterator iterator = monitors.values().iterator(); iterator.hasNext();)
158 {
159 holder = (ExpirableHolder) iterator.next();
160 removeExpirable(holder.getExpirable());
161 try
162 {
163 holder.getExpirable().expired();
164 }
165 catch (Exception e)
166 {
167
168 logger.debug(e.getMessage());
169 }
170 }
171 }
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 {
182 this.nanoseconds = nanoseconds;
183 this.expirable = expirable;
184 created = Utils.nanoTime();
185 }
186
187 public long getNanoSeconds()
188 {
189 return nanoseconds;
190 }
191
192 public Expirable getExpirable()
193 {
194 return expirable;
195 }
196
197 public boolean isExpired()
198 {
199 return (Utils.nanoTime() - nanoseconds) > created;
200 }
201
202 public void reset()
203 {
204 created = Utils.nanoTime();
205 }
206 }
207 }