0

I'm trying to implement following scenario and unable to come up with a solution.

In my web service I've cache object (contains static data) based on the session id. Once request is received it checks whether cache contains any key for the session id.

  1. If not available, it will load it from DB and stores it in cache.
  2. If available it uses that cache and continues with further processing.

Now, with multithreading enabled in this service and when multiple requests (with same session id) are sent to service, all of them are trying to load the data into cache as none of them find that key initially.

Question is: I wanted to stop all the other threads till the first thread loads static data into cache and once first thread is done with loading data in to cache, other threads should use that cache instead of trying to load again.

Looks trivial but somehow not able to think of any multi threading feature which can solve this.

My code looks something like below:

somemethod()
{
  if(cache.Contains(someKey)
  {
    // use cache and do further processing
  }
  else
  {
     cache.add(someKey)
  }
}
JPReddy
  • 63,233
  • 16
  • 64
  • 93

2 Answers2

0

You can try following logic 1) Thread1 for comes and finds that object is not present in cache 2) Puts a wait command object in cache for this session Id. This object tells any other threads to wait till further notice. 3) Thread1 fetches the data from DB and put it backs into cache. 4) Thread1 notifies other threads that they can proceed since data is now available.

soban
  • 41
  • 4
0

Classic remedy againsnt the race condition is mutual exclusion. Locking is the simplest solution providing such capability.

public class Cache
{
    private object _locker = new object();
    private SessionDataCollection _cache;

    public SessionData Get(SessionId id)
    {
        lock (_locker)
        {
            if (!Contains(id))
                Fetch(id);

            return Retrieve(id);
        }
    }

    private bool Contains(SessionId id)
    {
        //check if present in _cache
    }

    private void Fetch(SessionId id)
    {
        //get from db and store in _cache
    }

    private SessionData Retrieve(SessionId id)
    {
        //retrvieve from _cache
    }
}
Kimi
  • 13,621
  • 9
  • 55
  • 84