Caching
|
Caching not available in Axon Framework 5.1
The Caching feature is not yet available in Axon Framework 5.1. It will be reintroduced in Axon Framework 5.2. The documentation below describes the Caching concepts for reference and future use. |
A well-designed command handling module should pose no problems when implementing caching. Especially when using event sourcing, loading an aggregate from an Event Store can be an expensive operation. With a properly configured cache in place, loading an aggregate can be converted into a pure in-memory process.
To that end, Axon allows the configuration of a Cache object.
The framework currently provides several implementations to choose from:
-
WeakReferenceCache- An in-memory cache solution. In most scenarios, this is a good start. -
EhCacheAdapter- AnAbstractCacheAdapter, wrapping EhCache into a usable solution for Axon. This can be used with major version 2, and is therefore deprecated. -
EhCache3Adapter- AnAbstractCacheAdapter, wrapping EhCache into a usable solution for Axon. This can be used only with major version 3. Which has a different group name than version 2. -
JCacheAdapter- AnAbstractCacheAdapter, wrapping JCache into a usable solution for Axon. -
AbstractCacheAdapter- Abstract implementation towards supporting Axon’sCacheAPI. Helpful in writing an adapter for a cache implementation that Axon does not support out of the box.
Before configuring a Cache, please consider the following guidelines.
They will help you get the most out of your caching solution:
-
Make sure the unit of work never needs to perform a rollback for functional reasons. A rollback means that an aggregate has reached an invalid state. Axon will automatically invalidate the cache entries involved. The following request will force the aggregate to be reconstructed from its events. If you use exceptions as a potential (functional) return value, you can configure a
RollbackConfigurationon your command bus. By default, the configuration will roll back the unit of work on unchecked exceptions for command handlers and on all exceptions for event handlers. -
All commands for a single aggregate must arrive on the machine with the aggregate in its cache. This requirement means that commands should be consistently routed to the same machine for as long as that machine is "healthy." Routing commands consistently prevents the cache from going stale. A hit on a stale cache will cause a command to be executed and fail when events are stored in the event store. By default, Axon’s distributed command bus components will use consistent hashing to route commands.
-
Configure a sensible time to live / time to idle. By default, caches tend to have a relatively short time to live, a matter of minutes. For a command handling component with consistent routing, a longer time-to-idle and time-to-live is usually better. This setting prevents the need to re-initialize an aggregate based on its events because its cache entry expired. The time-to-live of your cache should match the expected lifetime of your aggregate.
-
Cache data in-memory. For proper optimization, caches should keep data in-memory (and preferably on-heap) for best performance. This approach prevents the need to (re)serialize aggregates when storing to disk and even off-heap.
To configure a cache for your Aggregates, consider the following snippet:
Axon Configuration API
public class AxonConfig {
// omitting other configuration methods...
public void configureAggregateWithCache(Configurer configurer) {
AggregateConfigurer<GiftCard> giftCardConfigurer =
AggregateConfigurer.defaultConfiguration(GiftCard.class)
.configureCache(config -> new WeakReferenceCache());
configurer.configureAggregate(giftCardConfigurer);
}
}
Spring Boot auto configuration
The Aggregate annotation allows specification of the cache bean:
@Aggregate(cache = "giftCardCache")
public class GiftCard {
// state, command handlers and event sourcing handlers...
}
This approach does require the bean name to be present in the Application Context of course:
@Configuration
public class AxonConfig {
// omitting other configuration methods...
@Bean
public Cache giftCardCache() {
return new WeakReferenceCache();
}
}