KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mr > core > util > TimeoutTimer


1 /*
2  * Copyright 2002 by
3  * <a HREF="http://www.coridan.com">Coridan</a>
4  * <a HREF="mailto: support@coridan.com ">support@coridan.com</a>
5  *
6  * The contents of this file are subject to the Mozilla Public License Version
7  * 1.1 (the "License"); you may not use this file except in compliance with the
8  * License. You may obtain a copy of the License at
9  * http://www.mozilla.org/MPL/
10  *
11  * Software distributed under the License is distributed on an "AS IS" basis,
12  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13  * for the specific language governing rights and limitations under the
14  * License.
15  *
16  * The Original Code is "MantaRay" (TM).
17  *
18  * The Initial Developer of the Original Code is Amir Shevat.
19  * Portions created by the Initial Developer are Copyright (C) 2006
20  * Coridan Inc. All Rights Reserved.
21  *
22  * Contributor(s): all the names of the contributors are added in the source
23  * code where applicable.
24  *
25  * Alternatively, the contents of this file may be used under the terms of the
26  * LGPL license (the "GNU LESSER GENERAL PUBLIC LICENSE"), in which case the
27  * provisions of LGPL are applicable instead of those above. If you wish to
28  * allow use of your version of this file only under the terms of the LGPL
29  * License and not to allow others to use your version of this file under
30  * the MPL, indicate your decision by deleting the provisions above and
31  * replace them with the notice and other provisions required by the LGPL.
32  * If you do not delete the provisions above, a recipient may use your version
33  * of this file under either the MPL or the GNU LESSER GENERAL PUBLIC LICENSE.
34  
35  *
36  * This library is free software; you can redistribute it and/or modify it
37  * under the terms of the MPL as stated above or under the terms of the GNU
38  * Lesser General Public License as published by the Free Software Foundation;
39  * either version 2.1 of the License, or any later version.
40  *
41  * This library is distributed in the hope that it will be useful, but WITHOUT
42  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
43  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
44  * License for more details.
45  */

46 /*
47  * Created on Jan 13, 2004
48  * Manta LTD
49  */

50 package org.mr.core.util;
51
52 import java.util.ArrayList JavaDoc;
53 import java.util.HashMap JavaDoc;
54 import java.util.Iterator JavaDoc;
55
56 import org.apache.commons.logging.Log;
57 import org.apache.commons.logging.LogFactory;
58 import org.mr.MantaAgent;
59
60 /**
61  * TimeoutTimer - when given a Timeoutable interface , an event key and a long interval
62  * this object will call the interface with the event after the interval has passed
63  * Created Jan 13, 2004
64  * Ver 1.0
65  * @author Amir Shevat
66  *
67  */

68 public class TimeoutTimer extends Thread JavaDoc{
69     
70     // the current minimal time out for this instance
71
private long minTimeToLive ;
72     // any timeout under this time will be discard
73
private long systemMinTTL;
74     // the registry will lookup time out connections in minimum TTL * ttlFactor
75
double ttlFactor;
76     
77     int numOfTimeouts = 0;
78     // the key is event ( the key for the next map) the value is the ttl
79
HashMap JavaDoc timeouts = new HashMap JavaDoc();
80     // key event of time out value timeoutable
81
HashMap JavaDoc timeoutables = new HashMap JavaDoc();
82     Log log ;
83     
84     // the next set of objects are improvment in the case
85
// there only one or less timeout request
86
// at any given time
87
Timeoutable singleTimeoutable;
88     Object JavaDoc singleEvent;
89     long singleTtl;
90     
91     /**
92      * @param registry
93      */

94     public TimeoutTimer(String JavaDoc name) {
95         this(name, Long.parseLong(MantaAgent.getInstance().getSingletonRepository().getConfigManager().getStringProperty("timer.min_ttl","1000"))
96                 ,Double.parseDouble(MantaAgent.getInstance().getSingletonRepository().getConfigManager().getStringProperty("timer.ttl_factor","0.1")) );
97         
98     }
99     
100     /**
101      *
102      * @param minTTL any timeout under this time will be discard
103      * @param ttlFactor the registry will lookup timeouts in minimum TTL * ttlFactor intervals
104      */

105     public TimeoutTimer(String JavaDoc name ,long minTTL , double ttlFactor) {
106         log=LogFactory.getLog("TimeoutTimer");
107         this.setName("TimeoutMonitor"+name);
108     
109         this.systemMinTTL =minTTL;
110         this.ttlFactor = ttlFactor;
111         minTimeToLive = systemMinTTL;
112     }
113     
114     /**
115      * add a timeout event
116      * @param timeoutable the object to be notified when timed out
117      * @param event the event to be passed to the timeoutable (links to the timeout when doing removeTimeout
118      * @param ttl time untill timeout
119      */

120     public synchronized void addTimeout(Timeoutable timeoutable ,Object JavaDoc event , long ttl) {
121         if(timeoutable == null || event== null)
122             throw new IllegalArgumentException JavaDoc("Timeoutable and event object must not be null ");
123         if(!this.isAlive())
124             this.start();
125         if(minTimeToLive > ttl ) this.setMinTimeToLive(ttl);
126         long now =SystemTime.currentTimeMillis();
127         if(numOfTimeouts == 0){
128             singleTimeoutable = timeoutable;
129             singleEvent = event;
130             singleTtl = ttl+now;
131         }else{
132             timeouts.put(event , new Long JavaDoc(ttl+now));
133             timeoutables.put(event , timeoutable);
134         }
135         numOfTimeouts ++;
136                 
137     }
138     /**
139      * @param event removes the timeout linked to this event
140      */

141     public synchronized void removeTimeout(Object JavaDoc event) {
142         if(event == null)
143             return;
144         Object JavaDoc removed = null;
145         if(singleEvent == event){
146             removed = event;
147             singleEvent = null;
148             singleTimeoutable = null;
149         }else{
150             removed = timeouts.remove(event );
151             timeoutables.remove(event );
152         }
153         
154         if(removed != null)
155             numOfTimeouts--;
156     }
157
158     /**
159      * @return Returns the minTimeToLive.
160      */

161     public long getMinTimeToLive() {
162         return minTimeToLive;
163     }
164
165     /**
166      * @param minTimeToLive The minTimeToLive to set.
167      */

168     private void setMinTimeToLive(long minTimeToLive) {
169         if(minTimeToLive < systemMinTTL){
170             if(log.isErrorEnabled()){
171                 log.error(" Not setting 'time to live' because it seems too short: ttl = "+minTimeToLive + ", system minimal ttl ="+systemMinTTL+".");
172             }
173             throw new IllegalArgumentException JavaDoc(" Time to live seems to short ttl = "+minTimeToLive + ", system minimal ttl ="+systemMinTTL+".");
174         }
175         this.minTimeToLive = minTimeToLive;
176     }
177     
178     
179     public void run(){
180         while(true){
181             try{
182                 long sleep = (long)(minTimeToLive * ttlFactor);
183                 Thread.sleep(sleep);
184                 checkForTimeouts();
185             }catch(Throwable JavaDoc t ){
186                 if(log.isFatalEnabled())
187                     log.fatal("Exception in connection timeout monitor, still running ",t);
188             }
189         }
190     }//run
191

192     ArrayList JavaDoc timeoutablesList =new ArrayList JavaDoc();
193     ArrayList JavaDoc timeoutablesEventList =new ArrayList JavaDoc();
194     
195     /**
196      * goes over the timeout and notifies the proper timeoutables
197      *
198      */

199     public void checkForTimeouts(){
200         
201         timeoutablesList.clear();
202         timeoutablesEventList.clear();
203         synchronized(this){
204             // collect the the objects that needs timeout
205
Iterator JavaDoc iter = this.timeouts.keySet().iterator();
206             long now =SystemTime.currentTimeMillis();
207             while(iter.hasNext()){
208                 Object JavaDoc event = iter.next();
209                 Long JavaDoc ttl =(Long JavaDoc) this.timeouts.get(event);
210                 if(ttl.longValue() < now){
211                     timeoutablesEventList.add(event);
212                     timeoutablesList.add(this.timeoutables.remove(event));
213                     numOfTimeouts--;
214                 }
215             }//while
216
// remove the objects
217
// so we do not get cuncurent modification we remove at a different stage
218
int size =timeoutablesEventList.size();
219             for(int index = 0 ;index<size ; index++){
220                 this.timeouts.remove(timeoutablesEventList.get(index));
221             }
222             
223             // check single case
224
if(singleEvent != null && singleTtl < now){
225                 timeoutablesEventList.add(singleEvent);
226                 timeoutablesList.add(singleTimeoutable);
227                 singleEvent =null;
228                 singleTimeoutable = null;
229                 numOfTimeouts--;
230             }
231             
232         }//synchronized
233

234         // now that we are out of the synchronized block we can timeout
235
// this is done to prevent deadlocks that happened with a missuse fo this util
236
int size =timeoutablesEventList.size();
237         for(int index = 0 ;index<size ; index++){
238             Timeoutable timeoutable = (Timeoutable)timeoutablesList.get(index);
239             if(timeoutable != null)
240                 timeoutable.timeout(timeoutablesEventList.get(index));
241         }
242         
243     }//checkForTimeouts
244

245     
246
247 }
248
Popular Tags