I have the following caching problem:
// imagine we have a method that performs a long running batch query List<Record> fetchRecords(List<String> recordKeys)
We would like to cache the results of this long running operation using the individual record key as the cache key instead of the whole list
The benefit of this outcome is obvious. Namely, upon the next invocation of fetchRecords(overlappingRecordKeys)
the long running batch query will only include those keys that have not been previously included. This is a benefit we don't get by testing equality on the entire List
.
This cannot be solved via keyGenerator
interceptor as that mechanism only allow us to return a single cache key per invocation of the method
What is the best approach for solving this problem? I can think of two solutions
Solution 1
Create a CachingAspect
// pseudo code
@Aspect
class CachingAspect {
CacheManager mgr = ...
@Around("somePointcut")
void checkCache(ProceedingPointCut pc) {
// grab args from 'pc' which is of type List<String>
// check against 'mgr', modify the argument to exclude those records already in cache
// capture the output (i.e. new records from long-running operation), append with records retrieved from cache, return the union
}
}
Solution 2
Same idea as above without AOP (put the code in fetchRecords()
directly. This has the benefit of added type safety at the cost of elegance
Which solution is better? Or is there a third superior approach?
Aucun commentaire:
Enregistrer un commentaire