Does .get() on a Caffeine AsyncLoadingCache prevent concurrent loads, by delaying subsequent threads which are calling .get() until the first one completes? Or that it can be configured to return a stale value while a self-populating load request is occurring?
This is so that a thundering herd can be prevented by using the cache.
I am seeing behavior which indicates that the thundering herd is not handled even though I am using a cache.
I create the cache like so:
val queryResponseCache: AsyncLoadingCache<Request, Response> = Caffeine.newBuilder()
.maximumSize(1000)
.expireAfterWrite(5, TimeUnit.SECONDS)
.recordStats()
.buildAsync(queryLoader)
And use it in conjunction with a L2 cache in redis like so (kotlin elvis operator):
queryResponseCache.getIfPresent(key) ?: fetchFromRedis(key) ?: queryResponseCache.get(key)
I understand that getIfPresent is concurrent, but the subsequent calls which end up calling fetchFromRedis() / get() seem to have problems. I guess moving the fetchFromRedis
into the asyncLoad()
function might be better for load tolerance.