Skip to content

Client-Side Caching - Enhancing Thread-Safety in Key Retrieval #2402

@GuyKomari

Description

@GuyKomari

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;
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions