![JAR search and dependency download from the Maven repository](/logo.png)
org.apache.river.landlord.FixedLeasePeriodPolicy Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.river.landlord;
import net.jini.core.lease.Lease;
import net.jini.core.lease.LeaseDeniedException;
/**
* Simple implementation of LeasePeriodPolicy
that grants
* lease times based on a fixed default and maximum lease. Will grant
* renewals longer than the maximum if the current lease and the
* request are both longer than the maximum.
*
* @author Sun Microsystems, Inc.
* @since 2.0
*/
public class FixedLeasePeriodPolicy implements LeasePeriodPolicy {
/** Under normal circumstances, the maximum lease or renewal to grant */
final private long maximum;
/** The default lease length */
final private long defaultLength;
/**
* Create a new FixedLeasePeriodPolicy
with
* the specified values for the maxium and default lease
* lengths.
* @param maximum the length in milliseconds of the longest lease
* this object should normally grant
* @param defaultLength the length in milliseconds of the
* default lease grants
* @throws IllegalArgumentException if either argument
* is not positive.
*/
public FixedLeasePeriodPolicy(long maximum, long defaultLength) {
if (maximum <= 0)
throw new IllegalArgumentException("FixedLeasePeriodPolicy:" +
"maximum lease time must be larger than 0, " +
"passed:" + maximum);
if (defaultLength <= 0)
throw new IllegalArgumentException("FixedLeasePeriodPolicy:" +
"default lease time must be larger than 0, " +
"passed:" + defaultLength);
this.maximum = maximum;
this.defaultLength = defaultLength;
}
/**
* Returns the duration this policy is willing to grant for the
* passed resource at this time. The duration actually granted
* will be shorter if the duration extends pass the end of the
* epoch. Must return a positive number.
*
* Note the duration returned by this method will be shorter than
* the final duration granted if the requested duration extends
* past the current expiration, and duration return by this
* method is before the current expiration.
*
* @param resource the resource having a lease granted
* or renewed
* @param requestedDuration the duration the client wants
* @return duration in milliseconds.
* @exception IllegalArgumentException thrown if requestedDuration
* is less than 0 and not equal to
* Lease.ANYLENGTH
or
* Lease.FOREVER
.
*/
protected long calculateDuration(LeasedResource resource,
long requestedDuration)
{
if (requestedDuration == Lease.FOREVER)
requestedDuration = Long.MAX_VALUE;
else if (requestedDuration == Lease.ANY)
requestedDuration = defaultLength;
else if (requestedDuration < 0)
throw new
IllegalArgumentException("Negative lease duration " +
"requested");
return Math.min(requestedDuration, maximum);
}
/**
* Method that provides some notion of the current time in milliseconds
* since the beginning of the epoch. Default implementation
* calls System.currentTimeMillis()
* @return current time in milliseconds.
*/
protected long currentTime() {
return System.currentTimeMillis();
}
/**
* Calculates an expiration based on the passed time and a requested
* duration. Will clip the expiration to the end of the epoch
* @param preferredDuration the duration the policy wants to grant
* @param now the current time in milliseconds since
* the beginning of the epoch
* @return the new expiration time for the lease in milliseconds since
* the beginning of the epoch
*/
private long calcExpiration(long preferredDuration, long now) {
long expiration = now + preferredDuration;
// Any addition of two positive longs is guaranteed to be
// negative if it overflowed
if (expiration < 0) {
// Not enough time for the duration we want, set to end of
// epoch
return Long.MAX_VALUE;
}
return expiration;
}
public Result grant(LeasedResource resource, long requestedDuration)
throws LeaseDeniedException
{
final long now = currentTime();
final long expiration =
calcExpiration(calculateDuration(resource, requestedDuration),
now);
final long duration = expiration - now;
return new Result(expiration, duration);
}
public Result renew(LeasedResource resource, long requestedDuration)
throws LeaseDeniedException
{
final long now = currentTime();
// The new expiration we would grant independent of the
// current expiration time
long newExpiration =
calcExpiration(calculateDuration(resource, requestedDuration),
now);
// Do not change the expiration time to be sooner that it is
// now unless the client explicitly asked for it. If they did
// ask for a sooner expiration give them exactly what they
// asked for.
// The current expiration of the lease
final long oldExpiration = resource.getExpiration();
if (oldExpiration > newExpiration) {
// need to make sure they asked for it
if (requestedDuration == Lease.ANY) {
// they did not explicitly ask for a sooner
// expiration, give them at least what they had
newExpiration = oldExpiration;
} else {
// The new expiration time they are requesting
// (possibly clipped to the end of the epoch) this is
// not affected by what we are willing to grant.
// [Note we know at this point that requestedDuration
// is >= 0]
final long requestedExpiration = calcExpiration(
requestedDuration, now);
if (requestedExpiration > oldExpiration) {
// they made a request for something longer, give
// them at least what they had
newExpiration = oldExpiration;
} else {
// They made a request for something shorter,
// give them what they at least what they want
newExpiration = requestedExpiration;
}
}
}
// Now that we finally have decided on a new expiration,
// get the real duration and return the result.
return new Result(newExpiration, newExpiration - now);
}
}