Caching
The Axelor Open Platform provides a generic caching interface that wraps various cache implementations, providing a unified API for caching operations. The API aims to stay close to Google’s Guava Cache and Caffeine, while adding support for potentially distributed caching.
See Global and Component-specific Cache Configurations for application configuration details.
AxelorCache Interface
The AxelorCache
interface offers a range of methods for managing cached data:
Method | Description |
---|---|
|
Retrieves or computes the values associated with the keys. |
|
Associates values with the keys. |
|
Discards cached entries. |
|
Provides an approximate count of cache entries, accounting for concurrent and pending updates. |
|
Returns a thread-safe |
|
Offers a key-specific reentrant lock for managing concurrent access to cache entries. |
CacheBuilder
The CacheBuilder
class is used to configure and construct AxelorCache
instances.
Builder Creation
-
newBuilder(name)
: Creates a cache builder supporting either in-memory or distributed caching, depending on application configuration. The name, combined with the caller class, forms a globally unique cache identifier that is used in case of distributed caching. -
newInMemoryBuilder()
: Creates a builder for an in-memory cache. This is useful when you need in-memory caching while usingAxelorCache
API.
Builder Options
-
maximumSize(size)
: Sets the maximum number of entries the cache can hold. -
expireAfterWrite(duration)
: Configures entries to expire after a specified duration following their last write operation. -
expireAfterAccess(duration)
: Configures entries to expire after a specified duration following their last access. -
weakKeys()
andweakValues()
: Specifies the use of weak references for keys or values, allowing garbage collection if no strong references exist. -
removalListener(listener)
: Attaches a listener to be notified when entries are removed from the cache.
Support of these various options depends on the underlying cache implementation and may be approximated or ignored if not supported at all. |
Usage Example
private static final AxelorCache<String, Action> ACTIONS =
CacheBuilder.newBuilder("actions").maximumSize(1000).weakValues().build(XMLViews::findAction);
Here, the cache is configured with a maximum size of 1000 entries and uses weak references for values. The XMLViews::findAction
loader dynamically loads actions not present in the cache.
In case of distributed caching, you need to make sure cache keys/values are serializable by the underlying cache implementation.
For example, when using Redisson, keys/values should be serializable by its codec, the default codec being org.redisson.codec.Kryo5Codec .
|
DistributedFactory
DistributedFactory
is a utility class that facilitates concurrency control in distributed cache environments. It provides static methods to access distributed-aware synchronization primitives, ensuring thread safety across multiple application instances when using distributed caching systems.
-
getLock(name)
: Returns a distributed-aware reentrant lock for the specified name, prefixed with the caller class name for uniqueness. This lock can be used to synchronize access to shared resources or cache entries in a distributed setup. -
getLockIfDistributed(name)
: Returns a lock only if the cache is configured for distribution; otherwise, it provides a no-op lock, avoiding unnecessary synchronization overhead in single-instance setups. -
getAtomicLong(name)
: Returns a distributed-aware atomic long for the specified name, useful for maintaining counters or sequence numbers across distributed instances.
These utilities are essential for applications leveraging distributed caches, as they ensure consistent and safe access to cached data in multi-node deployments.