
org.simpleframework.util.lease.Invoker Maven / Gradle / Ivy
/*
* Invoker.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;
/**
* The Invoker
object 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 Invoker extends Thread {
/**
* 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 Invoker
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 recieve expiration notifications
*/
public Invoker(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.
*/
@Override
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.
*
* @param lease this is the contract that contains details
*/
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