View Javadoc
1 /*** 2 * Redistribution and use of this software and associated documentation 3 * ("Software"), with or without modification, are permitted provided 4 * that the following conditions are met: 5 * 6 * 1. Redistributions of source code must retain copyright 7 * statements and notices. Redistributions must also contain a 8 * copy of this document. 9 * 10 * 2. Redistributions in binary form must reproduce the 11 * above copyright notice, this list of conditions and the 12 * following disclaimer in the documentation and/or other 13 * materials provided with the distribution. 14 * 15 * 3. The name "Exolab" must not be used to endorse or promote 16 * products derived from this Software without prior written 17 * permission of Exoffice Technologies. For written permission, 18 * please contact info@exolab.org. 19 * 20 * 4. Products derived from this Software may not be called "Exolab" 21 * nor may "Exolab" appear in their names without prior written 22 * permission of Exoffice Technologies. Exolab is a registered 23 * trademark of Exoffice Technologies. 24 * 25 * 5. Due credit should be given to the Exolab Project 26 * (http://www.exolab.org/). 27 * 28 * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS 29 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT 30 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 31 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 32 * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 33 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 34 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 35 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 39 * OF THE POSSIBILITY OF SUCH DAMAGE. 40 * 41 * Copyright 2000-2001,2003 (C) Exoffice Technologies Inc. All Rights Reserved. 42 * 43 * $Id: LeaseManager.java,v 1.22 2003/10/29 04:58:32 tanderson Exp $ 44 * 45 * Date Author Changes 46 * 3/01/2000 jima Created 47 */ 48 package org.exolab.jms.lease; 49 50 51 import org.apache.commons.logging.Log; 52 import org.apache.commons.logging.LogFactory; 53 54 import org.exolab.core.service.BasicService; 55 import org.exolab.core.service.ServiceException; 56 import org.exolab.core.service.ServiceState; 57 import org.exolab.core.util.OrderedQueue; 58 import org.exolab.jms.message.MessageHandle; 59 60 61 /*** 62 * The LeaseManager is responsible for creating and managing the lease objects. 63 * The Leasemanager is a singleton. When a BaseLease object is created it is 64 * added to the queue according to the duration (i.e. leases with shorter 65 * durations are placed at the top of the queue. 66 * <p> 67 * When the lease expires the LeeaseManager calls the leasee's associated 68 * listener(s). 69 * <p> 70 * We need to cater for persistence and non-persistent leases 71 * 72 * @version $Revision: 1.22 $ $Date: 2003/10/29 04:58:32 $ 73 * @author <a href="mailto:jima@intalio.com">Jim Alateras</a> 74 */ 75 public class LeaseManager extends BasicService { 76 77 /*** 78 * The name of the LeaseManagerThread that scans and removes expired leases 79 */ 80 private static final String LEASE_MANAGER_THREAD_NAME = 81 "LeaseManagerReaper"; 82 83 /*** 84 * An ordered list of leases 85 */ 86 private OrderedQueue _queue = null; 87 88 /*** 89 * The singleton instance of the LeaseManager 90 */ 91 private static LeaseManager _instance = new LeaseManager(); 92 93 /*** 94 * Helper for waiting for leases to expire 95 */ 96 private final Object _waiter = new Object(); 97 98 /*** 99 * The logger 100 */ 101 private static final Log _log = LogFactory.getLog(LeaseManager.class); 102 103 104 /*** 105 * Create a new sorted tree set using the lease comparator as the 106 * sorting functor. 107 */ 108 protected LeaseManager() { 109 super(LEASE_MANAGER_THREAD_NAME); 110 _queue = new OrderedQueue(new LeaseComparator()); 111 } 112 113 /*** 114 * Return the singleton instance of the LeaseManager 115 * 116 * @return LeaseManager 117 */ 118 public static LeaseManager instance() { 119 return _instance; 120 } 121 122 /*** 123 * Create a message lease with the specified duration and the nominated 124 * listener. The listener does not to be specified but is merely a 125 * convenience argument. 126 * <p> 127 * The object must be non-null and the duration must be greater than zero. 128 * 129 * @param handle message handle 130 * @param duration lease duration 131 * @param listener object that implements the LeaseEvent- 132 * ListenerIfc 133 * @return MessageLease creared lease object or null if no lease 134 * is created 135 */ 136 public MessageLease createMessageLease(MessageHandle handle, 137 long duration, 138 LeaseEventListenerIfc listener) { 139 MessageLease result = null; 140 141 if ((handle != null) && (duration > 0)) { 142 result = new MessageLease(handle, duration, listener); 143 addLease(result); 144 } 145 146 return result; 147 } 148 149 /*** 150 * Create a lease on any object for the specified duration. If a listener 151 * is also provided then add it to the lease. Insert the lease in the queue 152 * and return an instance of the created lease. 153 * <p> 154 * The object must be non-null and the duration must be greater than zero. 155 * 156 * @param object leased object 157 * @param duration lease duration 158 * @param listener object that implements the LeaseEvent- 159 * ListenerIfc 160 * @return BaseLease creared lease object or null if no lease 161 * is created 162 */ 163 public BaseLease createLease(Object object, long duration, 164 LeaseEventListenerIfc listener) { 165 BaseLease result = null; 166 167 if ((object != null) && (duration > 0)) { 168 result = new BaseLease(object, duration, listener); 169 addLease(result); 170 } 171 172 return result; 173 } 174 175 /*** 176 * Remove the specified lease. 177 * 178 * @param lease lease to remove 179 * @return boolean true if successful; false otherwise 180 */ 181 public boolean removeLease(BaseLease lease) { 182 boolean result = false; 183 184 synchronized (_queue) { 185 result = _queue.remove(lease); 186 } 187 if (result) { 188 synchronized (_waiter) { 189 _waiter.notify(); 190 } 191 } 192 193 return result; 194 } 195 196 /*** 197 * Renew the lease on the specified object 198 * 199 * @param object object's whose lease we want to renew 200 * @param duration the new duration of the lease in ms 201 */ 202 public BaseLease renewLease(BaseLease lease, long duration) { 203 BaseLease newlease = null; 204 205 if ((lease != null) && (duration > 0)) { 206 synchronized (_queue) { 207 // check that the lease hasn't expired yet. 208 if (_queue.remove(lease)) { 209 lease.setDuration(duration); 210 _queue.add(lease); 211 newlease = lease; 212 synchronized (_waiter) { 213 _waiter.notify(); 214 } 215 } 216 } 217 } 218 219 return newlease; 220 } 221 222 /*** 223 * Remove all the leases from the queue. Do not expire any of them 224 */ 225 public void removeAll() { 226 synchronized (_queue) { 227 _queue.clear(); 228 } 229 } 230 231 /*** 232 * Returns the number of active leases 233 * 234 * @return the number of leases 235 */ 236 public int getLeaseCount() { 237 return _queue.size(); 238 } 239 240 /*** 241 * The run method will search for expired leases, remove them from the 242 * list and notify listeners 243 */ 244 public void run() { 245 while (getState() != ServiceState.STOPPED) { 246 expire(); 247 248 // wait until a lease is available, or the service is terminated 249 synchronized (_waiter) { 250 try { 251 _waiter.wait(); 252 } catch (InterruptedException ignore) { 253 } 254 } 255 } 256 } 257 258 /*** 259 * Stop the service. 260 * 261 * @throws ServiceException if the service fails to stop 262 */ 263 public void stop() throws ServiceException { 264 super.stop(); 265 synchronized (_waiter) { 266 _waiter.notifyAll(); 267 } 268 } 269 270 /*** 271 * Expires active leases 272 */ 273 protected void expire() { 274 while (_queue.size() > 0) { 275 BaseLease lease = null; 276 boolean expired = false; 277 synchronized (_queue) { 278 lease = (BaseLease) _queue.firstElement(); 279 if (lease == null) { 280 continue; 281 } 282 283 if (lease.getExpiryTime() <= System.currentTimeMillis()) { 284 // remove from the list and notify listeners 285 _queue.removeFirstElement(); 286 expired = true; 287 } 288 } 289 290 if (expired) { 291 lease.notifyLeaseExpired(); 292 } else { 293 // wait until the first element in the list is 294 // ready to expire 295 long time = lease.getExpiryTime() - 296 System.currentTimeMillis(); 297 298 if (time > 0) { 299 try { 300 synchronized (_waiter) { 301 _waiter.wait(time); 302 } 303 } catch (InterruptedException ignore) { 304 } 305 } 306 } 307 } 308 } 309 310 /*** 311 * Add a lease 312 * 313 * @param lease the lease to add 314 */ 315 protected void addLease(BaseLease lease) { 316 synchronized (_queue) { 317 _queue.add(lease); 318 if (_queue.firstElement() == lease) { 319 // inserted before the first element, so reset scan 320 synchronized (_waiter) { 321 _waiter.notify(); 322 } 323 } 324 } 325 } 326 327 328 } //-- LeaseManager

This page was automatically generated by Maven