Module stormpot
Package stormpot

Interface Expiration<T extends Poolable>


  • 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 and Poolable 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 method synchronized 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.

    Tip

    If the expiration is too slow, you can use every(long, TimeUnit) or every(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 a Reallocator, where you do the expensive expiration check in the reallocate 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 given fromTime and toTime 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 given SlotInfo 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 PoolableExpiration<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 the unit is null, then an IllegalArgumentException will be thrown.

        Type Parameters:
        T - The type of Poolable to check.
        Parameters:
        time - Poolables older than this, in the given unit, will be considered expired. This value must be at least 1.
        unit - The TimeUnit of the maximum permitted age. Never null.
        Returns:
        The specified time-based expiration policy.
      • after

        static <T extends PoolableExpiration<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, the toTime is less than the fromTime, or the unit is null, then an IllegalArgumentException will be thrown.

        Type Parameters:
        T - The type of Poolable 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 - The TimeUnit of the bounds values. Never null.
        Returns:
        The specified time-based expiration policy.
      • never

        static <T extends PoolableExpiration<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 of Poolable 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 and toTime 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. Never null.
        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.