-
public interface Expiration<T extends Poolable>
The expiration is used to determine if a given slot has expired, or otherwise become invalid.
Note that Expiration instances must be thread-safe, as they may be accessed concurrently by multiple threads. However, for a given
SlotInfo
andPoolable
instance, only a single thread will invoke the expiration at a time. This means that there is no need to synchronise on the SlotInfo or Poolable objects.The easiest way to ensure that an Expiration implementation is thread-safe, is to make sure that they never mutate any state. If they do, however, then they must do so in a thread-safe manner, unless the mutable state is contained within the SlotInfo or Poolable objects – in this case, the mutable state will be thread-local. Be aware that making the
hasExpired
methodsynchronized
will most likely severely reduce the performance and scalability of the pool.The Expiration can be invoked several times during a
claim
call, so it is important that the Expiration is fast. It can easily be the dominating factor in the performance of the pool.TipIf the expiration is too slow, you can use
every(long, TimeUnit)
orevery(long, long, TimeUnit)
to make an expiration that only performs the slow expiration check every few seconds, for instance.You can alternatively use a time-based expiration, such as
after(long, TimeUnit)
, that has been configured with a very low expiration time, like a few seconds. Then you can configure the pool to use aReallocator
, where you do the expensive expiration check in thereallocate
method, returning the same Poolable back if it hasn’t expired.Be aware, though, that such a scheme has to be tuned to the load of the application, such that the objects in the pool don’t all expire at the same time, leaving the pool empty.
- Author:
- Chris Vest <mr.chrisvest@gmail.com>
-
-
Method Summary
All Methods Static Methods Instance Methods Abstract Methods Default Methods Modifier and Type Method Description static <T extends Poolable>
Expiration<T>after(long fromTime, long toTime, java.util.concurrent.TimeUnit unit)
Construct a new Expiration that will invalidate objects that are older than the given lower bound, before they get older than the upper bound, in the given time unit.static <T extends Poolable>
Expiration<T>after(long time, java.util.concurrent.TimeUnit unit)
Construct a new Expiration that will invalidate objects that are older than the exact provided span of time in the given unit.default Expiration<T>
every(long fromTime, long toTime, java.util.concurrent.TimeUnit unit)
Construct a new Expiration that is composed of a time-based expiration and this one, such that this expiration is only consulted at most once within a time period based on the givenfromTime
andtoTime
brackets.default Expiration<T>
every(long time, java.util.concurrent.TimeUnit unit)
Construct a new Expiration that is composed of a time-based expiration and this one, such that this expiration is only consulted at most once within the given time period.boolean
hasExpired(SlotInfo<? extends T> info)
Test whether the Slot and Poolable object, represented by the givenSlotInfo
object, is still valid, or if the pool should deallocate it and allocate a replacement.static <T extends Poolable>
Expiration<T>never()
Construct a new Expiration that never invalidates any objects.default Expiration<T>
or(Expiration<T> other)
Construct a new Expiration that will invalidate objects if either this, or the given expiration, considers an object expired.
-
-
-
Method Detail
-
after
static <T extends Poolable> Expiration<T> after(long time, java.util.concurrent.TimeUnit unit)
Construct a new Expiration that will invalidate objects that are older than the exact provided span of time in the given unit.
This expiration does not make use of the slot info stamp.
If the
time
is less than one, or theunit
isnull
, then anIllegalArgumentException
will be thrown.- Type Parameters:
T
- The type ofPoolable
to check.- Parameters:
time
- Poolables older than this, in the given unit, will be considered expired. This value must be at least 1.unit
- TheTimeUnit
of the maximum permitted age. Nevernull
.- Returns:
- The specified time-based expiration policy.
-
after
static <T extends Poolable> Expiration<T> after(long fromTime, long toTime, java.util.concurrent.TimeUnit unit)
Construct a new Expiration that will invalidate objects that are older than the given lower bound, before they get older than the upper bound, in the given time unit.
The actual expiration time is chosen uniformly randomly within the given brackets, for each allocated object.
This expiration make use of the slot info stamp for storing the target expiration timestamp.
If the
fromTime
is less than 1, thetoTime
is less than thefromTime
, or theunit
isnull
, then anIllegalArgumentException
will be thrown.- Type Parameters:
T
- The type ofPoolable
to check.- Parameters:
fromTime
- Poolables younger than this, in the given unit, are not considered expired. This value must be at least 1.toTime
- Poolables older than this, in the given unit, are always considered expired. This value must be greater than or equal to the lowerBound.unit
- TheTimeUnit
of the bounds values. Nevernull
.- Returns:
- The specified time-based expiration policy.
-
never
static <T extends Poolable> Expiration<T> never()
Construct a new Expiration that never invalidates any objects.
This is useful for effectively disabling object expiration, for cases where that makes sense.
- Type Parameters:
T
- The type ofPoolable
to check.- Returns:
- An expiration that never invalidates objects.
-
or
default Expiration<T> or(Expiration<T> other)
Construct a new Expiration that will invalidate objects if either this, or the given expiration, considers an object expired.
This is a short-circuiting combinator, such that if this expiration invalidates the object, then the other expiration will not be checked.
This makes it easy to have an expiration that expires both on time, and some other criteria.
- Parameters:
other
- The other expiration to compose with.- Returns:
- A new expiration composed of this and the other expiration.
-
every
default Expiration<T> every(long time, java.util.concurrent.TimeUnit unit)
Construct a new Expiration that is composed of a time-based expiration and this one, such that this expiration is only consulted at most once within the given time period.
For instance, if an expiration is expensive, you can use this to only check it, say, every 5 seconds.
- Parameters:
time
- The time between checks.unit
- The unit of the time between checks.- Returns:
- An expiration that only delegates to this one every so often.
-
every
default Expiration<T> every(long fromTime, long toTime, java.util.concurrent.TimeUnit unit)
Construct a new Expiration that is composed of a time-based expiration and this one, such that this expiration is only consulted at most once within a time period based on the given
fromTime
andtoTime
brackets.For instance, if an expiration is expensive, you can use this to only check it, say, every 5 to 10 seconds.
- Parameters:
fromTime
- The minimum amount of time before a check becomes necessary.toTime
- The maximum amount of time before a check becomes necessary.unit
- The unit of the time between checks.- Returns:
- An expiration that only delegates to this one every so often.
-
hasExpired
boolean hasExpired(SlotInfo<? extends T> info) throws java.lang.Exception
Test whether the Slot and Poolable object, represented by the given
SlotInfo
object, is still valid, or if the pool should deallocate it and allocate a replacement.If the method throws an exception, then that is taken to mean that the slot is invalid. The exception will bubble out of the
claim
method, but the mechanism is implementation specific. For this reason, it is generally advised that Expirations do not throw exceptions.Note that this method can be called as often as several times per
claim
. The performance of this method therefor has a big influence on the perceived performance of the pool.If this implementation ends up being expensive, then the
every-combinator
can be used to construct a new expiration object that only performs the expensive check every so often.- Parameters:
info
- An informative representative of the slot being tested. Nevernull
.- Returns:
true
if the Slot and Poolable in question should be deallocated,false
if it is valid and eligible for claiming.- Throws:
java.lang.Exception
- If checking the validity of the Slot or Poolable somehow went wrong. In this case, the Poolable will be assumed to be expired.
-
-