Description
Feature Request
The existing implementation of the get method in the ClientSideCaching class fails to provide a mechanism that guarantees the exclusive access of a single thread to fetch a value from the Redis server for a specific key.
Consequently, under high concurrent load scenarios involving the same key, the current implementation may cause redundant and unnecessary calls to the Redis server.
Current implementation get:
@Override
public V get(K key) {
V value = cacheAccessor.get(key);
if (value == null) {
value = redisCache.get(key);
if (value != null) {
cacheAccessor.put(key, value);
}
}
return value;
}
Describe the solution you'd like
Utilize a local locking mechanism to guarantee that at any given time, only a single thread is permitted to retrieve a value from the Redis cache for a particular key.
private final ConcurrentHashMap<K, ReentrantLock> keyLocks = new ConcurrentHashMap<>();
public V get(K key) {
V value = cacheAccessor.get(key);
if (value == null) {
// Acquire a lock for this key
ReentrantLock lock = keyLocks.computeIfAbsent(key, k -> new ReentrantLock());
lock.lock();
try {
// Double-check to see if the value has been added by another thread
value = cacheAccessor.get(key);
// If the value is not in the cache, fetch it from Redis server and set it in client-cache
if (value == null) {
value = redisCache.get(key);
if (value != null) {
cacheAccessor.put(key, value);
}
}
} finally {
lock.unlock();
}
}
return value;
}