0

I'm looking to dynamically add new caches to an already initialized CaffeineCacheManager instance.

The class doesn't seem to have an obvious method to do this. I could add a new cache name via CaffeineCacheManager.getCacheNames().add() but i'm not sure thats the proper way.

I'm thinking this because the documentation of the method setCacheNames() basically states that you can't add any new caches after you've changed the collection once. Heres the actual documentation:

Specify the set of cache names for this CacheManager's 'static' mode. The number of caches and their names will be fixed after a call to this method, with no creation of further cache regions at runtime. Calling this with a null collection argument resets the mode to 'dynamic', allowing for further creation of caches again

Lastly there is the method registerCustomCache() that could be of use. But the documentation of this method is really confusing.

Register the given native Caffeine Cache instance with this cache manager, adapting it to Spring's cache API for exposure through getCache(java.lang.String). Any number of such custom caches may be registered side by side. This allows for custom settings per cache (as opposed to all caches sharing the common settings in the cache manager's configuration) and is typically used with the Caffeine builder API: registerCustomCache("myCache", Caffeine.newBuilder().maximumSize(10).build()) Note that any other caches, whether statically specified through setCacheNames(java.util.Collection<java.lang.String>) or dynamically built on demand, still operate with the common settings in the cache manager's configuration

The last part is especially confusing:

Note that any other caches, whether statically specified through setCacheNames(java.util.Collection<java.lang.String>) or dynamically built on demand, still operate with the common settings in the cache manager's configuration.

When i use registerCustomCache() to add a cache i'm basically building the cache dynamically and using this method allows for custom settings per cache but then a few lines below the documentation suddenly says that they all still operate with the common settings in the cache manager's configuration.

So i'm a bit confused now. Please tell me which method i should use to dynamically add a new cache to the cache manager.

Thank you

Maurice
  • 6,698
  • 9
  • 47
  • 104
  • I think the intent is that you can create multiple cache managers, so modifications shouldn't be necessary. Would that work for you use-case? (I'm not a Spring user, it's just what I've picked up from these threads) – Ben Manes Jan 19 '22 at 17:43
  • @BenManes i'm already working with multiple cache managers. I have a web application that has pages that can have multiple translations. I want to build a cache for each language that the web application supports. That way when a user requests a page in, say german, then the backend only has to look in the german cache of the cachemanager that belongs to that particular page type. If its empty then the database is queried – Maurice Jan 19 '22 at 18:12
  • What about having the language be part of the key so that a single cache serves the data? – Ben Manes Jan 19 '22 at 19:37
  • @BenManes i considered that approach but i'd rather have many smaller caches that are more easily searchable because of their smaller size then one large cache where all the translations are cached. – Maurice Jan 19 '22 at 20:04
  • If you mean for lookup performance then I don't think it will change much either way (assuming you don't do O(n) iterations, just normal per-key calls). The implementation is designed to scale up reads and writes, and in simulations I've found most eviction policies do better when larger as more data to draw insights from. Of course if you mean simplifying an application then that's separate and understandable to go with whatever makes the most sense for your team to manage. – Ben Manes Jan 19 '22 at 20:28
  • @BenManes `I've found most eviction policies do better when larger as more data to draw insights from`. But what about simple Cache lookups? Wouldn't these be faster when the total Cache size is kept small? – Maurice Jan 19 '22 at 23:02
  • 1
    You are saving nanoseconds at best. The cache scales reads [very well](https://github.com/ben-manes/caffeine/wiki/Benchmarks#read-100-1) so it is not your bottleneck. You certainly would always prefer a higher hit rate as misses are millis++. Writes can improve with the cache sizes as more locks are allocated. I would worry more about simplicity and clarity of your code and trust that the cache reads won’t be your bottleneck. Your idea is excellent if it was a synchronized lru, but we’ve moved beyond that in modern designs. – Ben Manes Jan 20 '22 at 02:32
  • @BenManes In your last comment you said; `Your idea is excellent if it was a synchronized lru`. what does `lru` stand for? – Maurice Jan 20 '22 at 02:51
  • Least Recently Used, like how one could use LinkedHashMap as a bounded cache. That is not threadsafe so as a cache one would wrap with Collections.synchronizedMap. Then the lock on every access would favor your approach. Caffeine is concurrent so it handles multithreaded reads very quickly. – Ben Manes Jan 20 '22 at 02:55
  • @BenManes In your profile you mention that you are working on Caffeine. Could you tell me if using `registerCustomCache()` is the proper way to dynamically add a new cache during run time? What would happen if i'd add a new `cacheName` to the collection returned by `getCacheNames()` instead? Thanks – Maurice Jan 20 '22 at 02:56
  • 1
    Sadly I don’t know as that is Spring’s integration. I only know the core library. – Ben Manes Jan 20 '22 at 02:57

0 Answers0