
org.simpleframework.util.lease.LeaseCleaner Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of simple Show documentation
Show all versions of simple Show documentation
Simple is a high performance asynchronous HTTP server for Java
The newest version!
/*
* LeaseCleaner.java May 2004
*
* Copyright (C) 2004, Niall Gallagher
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
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