001: /*
002: * $Id: ExpiryMonitor.java 10489 2008-01-23 17:53:38Z dfeist $
003: * --------------------------------------------------------------------------------------
004: * Copyright (c) MuleSource, Inc. All rights reserved. http://www.mulesource.com
005: *
006: * The software in this package is published under the terms of the CPAL v1.0
007: * license, a copy of which has been included with this distribution in the
008: * LICENSE.txt file.
009: */
010:
011: package org.mule.util.monitor;
012:
013: import org.mule.api.lifecycle.Disposable;
014:
015: import java.util.Iterator;
016: import java.util.Map;
017: import java.util.Timer;
018: import java.util.TimerTask;
019:
020: import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
021:
022: import org.apache.commons.logging.Log;
023: import org.apache.commons.logging.LogFactory;
024:
025: /**
026: * <code>ExpiryMonitor</code> can monitor objects beased on an expiry time and can
027: * invoke a callback method once the object time has expired. If the object does
028: * expire it is removed from this monitor.
029: */
030:
031: // TODO we should probably rewrite this with ScheduledExecutor for stability IF we
032: // need it; right now this class is unused
033: public class ExpiryMonitor extends TimerTask implements Disposable {
034: /**
035: * logger used by this class
036: */
037: protected static final Log logger = LogFactory
038: .getLog(ExpiryMonitor.class);
039:
040: private Timer timer;
041: private Map monitors;
042:
043: public ExpiryMonitor() {
044: this (1000);
045: }
046:
047: public ExpiryMonitor(long monitorFrequency) {
048:
049: timer = new Timer(true);
050: timer.schedule(this , monitorFrequency, monitorFrequency);
051: monitors = new ConcurrentHashMap();
052: }
053:
054: /**
055: * Adds an expirable object to monitor. If the Object is already being monitored
056: * it will be reset and the millisecond timeout will be ignored
057: *
058: * @param milliseconds
059: * @param expirable
060: */
061: public void addExpirable(long milliseconds, Expirable expirable) {
062: if (isRegistered(expirable)) {
063: resetExpirable(expirable);
064: } else {
065: if (logger.isDebugEnabled()) {
066: logger.debug("Adding new expirable: " + expirable);
067: }
068: monitors.put(expirable, new ExpirableHolder(milliseconds,
069: expirable));
070: }
071: }
072:
073: public boolean isRegistered(Expirable expirable) {
074: return (monitors.get(expirable) != null);
075: }
076:
077: public void removeExpirable(Expirable expirable) {
078: if (logger.isDebugEnabled()) {
079: logger.debug("Removing expirable: " + expirable);
080: }
081: monitors.remove(expirable);
082: }
083:
084: public void resetExpirable(Expirable expirable) {
085: ExpirableHolder eh = (ExpirableHolder) monitors.get(expirable);
086: if (eh != null) {
087: eh.reset();
088: if (logger.isDebugEnabled()) {
089: logger.debug("Reset expirable: " + expirable);
090: }
091: }
092: }
093:
094: /**
095: * The action to be performed by this timer task.
096: */
097: public void run() {
098: ExpirableHolder holder;
099: for (Iterator iterator = monitors.values().iterator(); iterator
100: .hasNext();) {
101: holder = (ExpirableHolder) iterator.next();
102: if (holder.isExpired()) {
103: removeExpirable(holder.getExpirable());
104: holder.getExpirable().expired();
105: }
106: }
107: }
108:
109: public void dispose() {
110: logger.info("disposing monitor");
111: timer.cancel();
112: ExpirableHolder holder;
113: for (Iterator iterator = monitors.values().iterator(); iterator
114: .hasNext();) {
115: holder = (ExpirableHolder) iterator.next();
116: removeExpirable(holder.getExpirable());
117: try {
118: holder.getExpirable().expired();
119: } catch (Exception e) {
120: // TODO MULE-863: What should we really do?
121: logger.debug(e.getMessage());
122: }
123: }
124: }
125:
126: private class ExpirableHolder {
127:
128: private long milliseconds;
129: private Expirable expirable;
130: private long created;
131:
132: public ExpirableHolder(long milliseconds, Expirable expirable) {
133: this .milliseconds = milliseconds;
134: this .expirable = expirable;
135: created = System.currentTimeMillis();
136: }
137:
138: public long getMilliseconds() {
139: return milliseconds;
140: }
141:
142: public Expirable getExpirable() {
143: return expirable;
144: }
145:
146: public boolean isExpired() {
147: return (System.currentTimeMillis() - milliseconds) > created;
148: }
149:
150: public void reset() {
151: created = System.currentTimeMillis();
152: }
153: }
154: }
|