Releases: chrisvest/stormpot
Stormpot 2.2
Lots of incremental improvements:
- False sharing has been reduced in the BlazePool implementation, improving performance.
- Numerous adjustments to the BlazePool implementation to improve inlining and optimisation behaviour, improving performance.
- Fix a bug in BlazePool where the exception in a poisoned slot could bubble out through
claim()
calls more than once. - Fix a bug where the
Allocator
could eat the interrupt that was meant to signal to the allocation thread that it should begin shutting down. This signal is now no longer missed. - Poisoned slots are now proactively reallocated, if possible. This way, a temporary outage that then resolves itself, won't leave the pool full of poisoned slots that each have to bubble up through a
claim()
call before they can be reallocated. Expiration.hasExpired()
is now allowed to throw exceptions.- A new
Reallocator
API has been added. It can potentially reduce old-gen garbage accretion, in cases where Poolable instances can be reused across deallocate/allocate calls. - A new
TimeSpreadExpiration
has been added and made the default Expiration. It prevents all slots in the pool from expiring all at once. - Tons of fuzzing and stress testing have been performed. No released bugs found, though.
Stormpot 2.1
New and very fast BlazePool implementation.
Stormpot 2.0
I have released version 2.0 of Stormpot, my Java object pooling library, to the Maven Central repositories. You can add it as a dependency in Maven like this:
<dependency>
<groupId>com.github.chrisvest</groupId>
<artifactId>stormpot</artifactId>
<version>2.0</version>
</dependency>
This version breaks backwards compatibility on a number of points, and introduces a couple of new features.
Stormpot now depends on Java6
Stormpot 1.0.1 can be used on Java5, but the new version 2.0 now needs at least Java6. The reason is something as benign as making use of new entries in the TimeUnit
enum. However, I do not have a version 5 of Java installed, and I therefore cannot truly test the compatibility with this version of Java. That is why I decided to depend on Java6 instead. If you want to use Stormpot 2.0 on Java5, then you should be able to pretty easily make a fork and port it.
New Timeout value objects
In Stormpot 1.0.1, timeouts is expressed as a combination of a long
value and a TimeUnit
. This is identical to the way that timeouts are expressed in java.util.concurrent
. However, it cannot be denied that this API pattern suffers from primitive obsession. Therefore, Stormpot 2.0 introduces a new Timeout
value object to replace this pattern. The Timeout
instances are immutable and thread-safe, and can easily be cached in static final fields.
No more blocking forever
Along side the introduction of the Timeout
, Stormpot 2.0 also removes all blocking methods from its API, that do not take a timeout. It is generally bad practice to perform a blocking operation without a timeout, but it can still be achieved by calling a method with a timeout, in a loop. This change also made testing easier.
Resizable pools
Stormpot 2.0 introduces a new ResizablePool abstraction. This interface exposes methods for setting and getting a target size for a pool. These methods are non-blocking, and the size of the pool is eventually consistent. This allows you to respond to contention by increasing the size of a pool. You can observe that a pool is contended if its claim
methods starts to return null
often, for some value of "often." Note that Stormpot always strives to keep exactly the target-size number of objects allocated at any one point. Stormpot is intentionally designed without low- and high-water marks, because it requires intimate knowledge of the whole system to figure out how best to respond to a load spike. Consider, for instance, the case where you have a number of application servers all connecting to the same database. If the app servers uses pools with low/high-water marks, and suddenly experience a load spike, then the number of new connections created by all these pools suddenly reaching for the high-water mark, might be too much for the database and cause it to crash. It is nice to have self-managing autonomous systems, as long as they don't autonomously make a bad situation worse.
Programmable expirations
Stormpot 2.0 introduces a new Expiration abstraction, and removes the previous time-to-live options from the Config class. By default, the Config
is set up with a TimeExpiration
that has the same exact effect as the previous 10 minute time-to-live. The Expiration
is a call-back interface (a SAM type) that pools use to determine if a given object has expired or not. To help make this decision, the Expiration.hasExpired
method gets a SlotInfo
object as a parameter. The SlotInfo
object holds information about the particular Slot
that represents the given object in the pool: how long ago it was allocated, how many times it has been claimed, and what object it holds. If the decision requires domain specific knowledge, then that can be put in the pooled objects themselves. This information should be enough to cover most use cases for programmable expiration.
Concluding
These features have all been implemented without reducing the performance of the pool, and without compromising the quality of the code. In fact, this release maintains the 100% test coverage in spite of implementing these new interacting features, and switching to an at least as thorough test coverage tool. If anything, the quality in this release have increased, as I have added mutation testing with PIT to the mix, and experimented with verifying the correctness of the concurrent behaviour with JPF and cJUnit. I also had the opportunity to get my code publicly peer-reviewed by the Good Code interest group at work, which yielded feedback of surprisingly good quality — I can recommend trying this to anyone, should the opportunity arise.
All in all, I am very pleased with this release. I don't know when the next one will be out, or what the headlines will be. I think I need a little break from the project now, but I guess the next version will probably be about actually adding alternative pool implementations, with different performance characteristics.
Full Changelog: https://github.com/chrisvest/stormpot/commits/stormpot-2.0