MemoryCache is not keeping the cache between different services for the same IIS site (WebApi 2)

2.2k views Asked by At

My goal using MemoryCache is to prevent the same user to login more than one time in my application.

I have 3 services registered in the same IIS site: user, navigation and evaluation services. I implemented the MemoryCache in my framework which is used as reference between all the services. I have a filter that verify whether I have the user token cached or not for every request made from any service.

When I login in my application, it will send 3 requests: 2 for the 'user' service and 1 for the 'navigation' service. The first request will set the cache using the 'user' service. At this time, I will have my object cached in memory. The second request uses the 'user' service again, which verifies that the token is there and return the result successfully.

My problem: The last request uses the 'navigation' service, and at this point, it can't access the cache (or the cache is no longer available) and throws an exception that I implemented.

IIS Site

Sites
-> APR
   -> API
      -> User
         -> V1 (application)
      -> Navigation
         -> V1 (application)
      -> Evaluation
         -> V1 (application)

Below is my code:

public static CacheItemPolicy policy = new CacheItemPolicy();
public static MemoryCache cache = MemoryCache.Default;

public static bool GetCache<T>(string key, out T output, T defaultValue)
{
    try
    {
        output = (T)cache.Get(key);
        if (output != null)
        {
            return true;
        }
    }
    catch { }

    output = defaultValue;
    return false;
}

public static void SetCache(string key, object obj, DateTime date)
{
    try
    {
        policy.AbsoluteExpiration = date;
        cache.Set(key, obj, policy);
    }
    catch { }
}

public static void RemoveCache(string key)
{
    cache.Remove(key);
}
2

There are 2 answers

0
pineal On BEST ANSWER

I realized that MemoryCache sets the cache in the application level of the IIS site. Even through I have the same site to host my services, each service has it own application, as you can see in my edited post. Thus, when the 'user' service sets the cache for the login request, it sets the cache in the memory of the 'user' service application. Therefore, when a request from the 'navigation' service is sent, it cannot access the 'user' service application.

As a solution, I had to guarantee that when a user login in my application, all the services must set the cache in the memory of its own application. Since the 'user' service already sets the cache for the login request, I created a simple request for each the 'navigation' and 'evaluation' services to set the cache in theirs service application. In this way, calling all these three requests just one time when the user login, all the services will have the token cached in memory.

0
Adam Kopciński On

Try to use Redis server, it is not application dependend. Should resolve your problem.