Reputation: 369
Using Spring Cache, I want to store in the cache the return value of a function with two parameters, but evict entries using only the first one, ignoring the second... a kind of hierarchical eviction.
Example:
@Cacheable(cacheNames = "myCache", cacheManager = "myCacheManager")
public String foo(Long id, String subId)
foo(1,"A");
foo(1,"B");`
foo(1,"C");
--
foo(2,"A");
foo(2,"B");
fooEvict(1); // Should evict all entries where id=1
@CacheEvict(cacheNames = "myCache", cacheManager = "myCacheManager")
public void fooEvict(Long id) {
LOG.debug("Should evict all entries where id= {} ", id);
}
Upvotes: 0
Views: 505
Reputation: 7991
Eviction algorithms are specific to caching provider and the capabilities vary widely from 1 caching provider to the next. It is also the reason Spring explicitly states Eviction (and Expiration) are not generally concerns handled by the framework itself given these concerns are implementation dependent.
Having said that, your mileage will vary depending on the caching provider you chose from the onset. For example, if you are using Redis, then it is possible to use Redis's API direcctly to accomplish a similar Eviction strategy using REGEX, which I actually saw from another SO post.
I was actually inspired by the question and took it upon myself to build a more generic solution to this problem that works with different caching providers under the hood.
In my test class (prototype), I tested 3 different caching provider implementations.
The first configuration, since my test is a Spring Boot test, just uses the default, "simple" caching provider implementation, which is a ConcurrentHashMap
.
The second configuration uses Redis, and as you can see, it employs the technique from the SO post I shared above.
The final configuration uses Apache Geode, an in-memory, distributed data store, like Hazelcast, that I am most familiar with, which can be used as caching provider in Spring's Cache Abstraction.
The rest of the code below is supporting infrastructure classes to make the generic solution possible across different caching providers.
In time, I plan to port this code to a new library that I am currently building that includes extensions for many things in Spring, including caching, which is my area of expertise at VMware.
The approach used in my test might be overkill for your UC. If so, then you can simply implement Spring's 2 primary interfaces in the Cache Abstraction responsible for caching behavior in the framework, the Cache
and CacheManger
interfaces.
You can do so using the Adapter
design pattern to wrap an existing caching provider implementation with the extended Eviction functionality you require.
Of course, there are many other ways to solve this problem, and hopefully this helps spur some ideas of your own.
If you have more questions, feel free to post in the comments below.
Upvotes: 1