All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.simpleframework.util.lease.LeaseCleaner Maven / Gradle / Ivy

Go to download

Simple is a high performance asynchronous HTTP server for Java

There is a newer version: 5.1.6
Show newest version
/*
 * LeaseCleaner.java May 2004
 *
 * Copyright (C) 2004, Niall Gallagher 
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General 
 * Public License along with this library; if not, write to the 
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
 * Boston, MA  02111-1307  USA
 */

package org.simpleframework.util.lease;

import static java.util.concurrent.TimeUnit.NANOSECONDS;

import org.simpleframework.util.thread.Daemon;

/**
 * The LeaseCleaner provides a means of providing
 * callbacks to clean a leased resource once the contract duration
 * has expired. This will acquire contracts from the queue and
 * invoke the Cleaner notification method. This will
 * wait until the current clean operation has completed before it
 * attempts to clean the next contract.
 *
 * @author Niall Gallagher
 */
class LeaseCleaner extends Daemon {

   /**
    * This is used to queue contracts that are to be cleaned.
    */
   private ContractQueue queue;        

   /**
    * This is the cleaner that is invoked to clean contracts.
    */
   private Cleaner cleaner;        

   /**
    * This is used to determine if the invoker should stop.
    */
   private volatile boolean dead;

   /**
    * Constructor for the LeaseCleaner object. This 
    * can be used to issue, update, and expire leases. When a lease
    * expires notification is sent to the Cleaner
    * object provided. This allows an implementation independent
    * means to clean up once a specific lease has expired.
    *
    * @param cleaner this will receive expiration notifications
    */   
   public LeaseCleaner(Cleaner cleaner) {
      this.queue = new ContractQueue();
      this.cleaner = cleaner;          
      this.start();
   }
   
   /**
    * This revokes a contract that has previously been issued. This
    * is used when the contract duration has changed so that it can
    * be reissued again with a new duration. This returns true if 
    * the contract was still active and false if it did not exist.
    *
    * @param contract this is the contract that contains details
    */
   public boolean revoke(Contract contract) throws LeaseException {
      if(dead) {
         throw new LeaseException("Lease can not be revoked");
      }
      return queue.remove(contract);
   }
   
   /**
    * This method will establish a contract for a given resource.     
    * If the contract duration expires before it is renewed then 
    * a notification is sent, to the issued Cleaner
    * implementation, to signify that the resource has expired.
    * 
    * @param contract this is the contract that contains details
    */   
   public boolean issue(Contract contract) throws LeaseException {
      if(dead) {
         throw new LeaseException("Lease can not be issued");
      }
      return queue.offer(contract);
   }

   /**
    * This acquires expired lease contracts from the queue once the
    * expiry duration has passed. This will deliver notification to
    * the Cleaner object once the contract has been 
    * taken from the queue. This allows the cleaner to clean up any
    * resources associated with the lease before the next expiration.
    */
   public void run() {
      while(!dead) {
         try {                         
            clean();            
         } catch(Throwable e) {
            continue;                 
         }
      }
      purge();
   }   
   
   /**
    * This method is used to take the lease from the queue and give
    * it to the cleaner for expiry. This effectively waits until the
    * next contract expiry has passed, once it has passed the key
    * for that contract is given to the cleaner to clean up resources.   
    */
   private void clean() throws Exception {      
      Contract next = queue.take();
      T key = next.getKey();

      if(key != null) {
         cleaner.clean(key);
      }
   } 
   
   /**
    * Here all of the existing contracts are purged when the invoker
    * is closed. This ensures that each leased resource has a chance
    * to clean up after the lease manager has been closed. All of the
    * contracts are given a zero delay and cleaned immediately such
    * that once this method has finished the queue will be empty.    
    */
   private void purge() {
      for(Contract next : queue) {
         T key = next.getKey();
         
         try {
            next.setDelay(0L, NANOSECONDS);         
            cleaner.clean(key);
         } catch(Throwable e) {
            continue;
         }
      }      
   }
   
   /**
    * Here we shutdown the lease maintainer so that the thread will
    * die. Shutting down the maintainer is done by interrupting the
    * thread and setting the dead flag to true. Once this is invoked
    * then the thread will no longer be running for this object.
    */
   public void close() {
      dead = true;     
      interrupt();            
   }       
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy