Simplest Possible Usage

Stormpot has an invasive API which means that there is a minimum of things your code needs to do to use it. However, the requirements are quite benign, as this section is all about showing you.

The objects that you manage with a Stormpot pool needs to implement the Poolable interface. The absolute minimum amount of code required for its implementation is this:

// MyPoolable.java - minimum Poolable implementation
import stormpot.BasePoolable;
import stormpot.Slot;

public class MyPoolable extends BasePoolable {
  public MyPoolable(Slot slot) {
    super(slot);
  }
}

We extend the BasePoolable class, pass a Slot argument through to its constructor, and leave the rest of the implementation to the BasePoolable class.

We can also implement the Poolable interface directly. Here is an example of how to do this:

// MyOtherPoolable.java - explicit Poolable implementation
import stormpot.Poolable;
import stormpot.Slot;

public class MyOtherPoolable implements Poolable {
  private final Slot slot;
  public MyOtherPoolable(Slot slot) {
    this.slot = slot;
  }

  @Override
  public void release() {
    slot.release(this);
  }
}

The object in essence just needs to keep its Slot instance around, and give itself as a parameter to the Slot#release method. Now that we have a class of objects to pool, we need some way to tell Stormpot how to create them. We do this by implementing the Allocator interface:

// MyAllocator.java - minimum Allocator implementation
import stormpot.Allocator;
import stormpot.Slot;

public class MyAllocator implements Allocator<MyPoolable> {
  public MyPoolable allocate(Slot slot) throws Exception {
    return new MyPoolable(slot);
  }

  public void deallocate(MyPoolable poolable) throws Exception {
    // Nothing to do here
    // But it's a perfect place to close sockets, files, etc.
  }
}

That’s it. Given a slot, create a MyPoolable. Or given a MyPoolable, deallocate it. And that is actually all the parts we need to start using Stormpot. All that is left is a little bit of configuration:

    Pool<MyPoolable> pool = Pool.from(new MyAllocator()).build();
    Timeout timeout = new Timeout(1, TimeUnit.SECONDS);

    MyPoolable object = pool.claim(timeout);
    try {
      // Do stuff with 'object'.
      // Note that 'claim' will return 'null' if it times out!
    } finally {
      if (object != null) {
        object.release();
      }
    }

We get a PoolBuilder via the Pool.from method, which takes an allocator. Then we use it to build a pool with the configuration we want, and off we go!

The blocking methods Pool#claim and Completion#await both take Timeout objects as arguments. These are immutable, and can easily be put in static final constants.

Note that claim returns null if the timeout elapses before an object can be claimed. Also, using try-finally is a great way to make sure that you don’t forget to release the objects back into the pool.

Stormpot cannot prevent objects from leaking in user code, so if you lose the reference to an object that hasn’t been released back into the pool, it will not come back on its own. Leaked objects can also cause problems with shutting the pool down, because the shut down procedure does not complete until all allocated objects are deallocated. So if you have leaked objects, shutting the pool down will never complete normally. You can still just halt the JVM, though.