Module stormpot
Package stormpot

Interface Allocator<T extends Poolable>

Type Parameters:
T - any type that implements Poolable.
All Known Subinterfaces:
Reallocator<T>
All Known Implementing Classes:
ReallocatingAdaptor

public interface Allocator<T extends Poolable>
An Allocator is responsible for the creation and destruction of Poolable objects.

This is where the objects in the Pool comes from. Clients of the Stormpot library needs to provide their own Allocator implementations.

Implementations of this interface must be thread-safe, because there is no knowing whether pools will try to access it concurrently or not. The easiest way to achieve this is to just make the allocate and deallocate methods synchronised, but this might cause problems for the pools ability to allocate objects fast enough, if they are very slow to construct. Pools might want to deal with very slow allocations by allocating in more than one thread, but synchronizing the allocate(Slot) method will render that strategy ineffective.

A better approach to thread-safety is to not have any shared mutable state in the allocator, if at all possible.

Implementations must also be interruption-safe. When a pool is shut down, its background allocation thread may be interrupted, and this thread may be interacting with the allocator instance when this happens.

Author:
Chris Vest
See Also:
  • Method Summary

    Modifier and Type
    Method
    Description
    allocate(Slot slot)
    Create a fresh new instance of T for the given slot.
    void
    deallocate(T poolable)
    Deallocate, if applicable, the given Poolable and free any resources associated with it.
  • Method Details

    • allocate

      T allocate(Slot slot) throws Exception
      Create a fresh new instance of T for the given slot.

      The returned Poolable must obey the contract that, when Poolable.release() is called on it, it must delegate the call onto the Slot.release(Poolable) method of the here given slot object.

      Exceptions thrown by this method may propagate out through the claim method of a pool, in the form of being wrapped inside a PoolException. Pools must be able to handle these exceptions in a sane manner, and are guaranteed to return to a working state if an Allocator stops throwing exceptions from its allocate method.

      Parameters:
      slot - The slot the pool wish to allocate an object for. Implementers do not need to concern themselves with the details of a pools slot objects. They just have to call release on them as the protocol demands.
      Returns:
      A newly created instance of T. Never null.
      Throws:
      Exception - If the allocation fails.
    • deallocate

      void deallocate(T poolable) throws Exception
      Deallocate, if applicable, the given Poolable and free any resources associated with it.

      This is an opportunity to close any connections or files, flush buffers, empty caches or what ever might need to be done to completely free any resources represented by this Poolable.

      Note that a Poolable must never touch its slot object after it has been deallocated.

      Pools, on the other hand, will guarantee that the same object is never deallocated more than once.

      Note that pools will always silently swallow exceptions thrown by the deallocate method. They do this because there is no knowing whether the deallocation of an object will be done synchronously by a thread calling release on a Poolable, or asynchronously by a clean-up thread inside the pool.

      Deallocation from the release of an expired object, and deallocation from the shutdown procedure of a Pool behave the same way in this regard. They will both silently swallow any exception thrown.

      On the other hand, pools are guaranteed to otherwise correctly deal with any exception that might be thrown. The shutdown procedure will still complete, and release will still maintain the internal data structures of the pool to make the slot available for new allocations.

      If you need to somehow specially deal with the exceptions thrown by the deallocation of objects, then you should do this in the allocator itself, or in a wrapper around your allocator.

      Parameters:
      poolable - The non-null Poolable instance to be deallocated.
      Throws:
      Exception - if the deallocation encounters an error.