Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to manage cache in ASP.NET WebApi2?

I have implemented REST service using WebAPI2, service implemeted to manage different sessions which are created and joined by different clients which are accessing service.

Session contains information about access of application functionality and information of participants which have joined same session.

Each client get session information and access list from server for synchronization purpose on every second. According to access changed, client functionality will changed(Enable/Disable).

I am using MemoryCache class to store session info in WebAPI service as below.

public static class SessionManager{
private static object objForLock = new object();
public static List<Session> SessionCollection
{
    get
    {
        lock (objForLock)
        {
            MemoryCache memoryCache = MemoryCache.Default;
            return memoryCache.Get("SessionCollection") as List<Session>;
            // return HttpContext.Current.Application["SessionCollection"] as List<Session>;
        }
    }
    set
    {
        lock (objForLock)
        {
            MemoryCache memoryCache = MemoryCache.Default;
            memoryCache.Add("SessionCollection", value, DateTimeOffset.UtcNow.AddHours(5));
            //HttpContext.Current.Application["SessionCollection"] = value;  
        }
    }
}

}

My problem is regarding inconsistent behavior of cache.

When clients send synchronization call, it will gives inconsistent results. For some requests, clients gets proper data and for some requests client gets null data alternative after some requests.

I have add debugger and monitor the object for null result, then "memoryCache.Get("SessionCollection")" also null. After some consecutive request it will be proper again. I am not getting why this object is not persistent.

Alternative, I have tried "HttpContext.Current.Application["SessionCollection"]" as well, But same issue is there.

I have read about "app pool recycle", it recycle all cache after particulate time. If my cached object is recycled by app pool recycle, then how can I get this object again?

Please some can help me to get out of this issue. Thanks in advance.

like image 964
Nilesh Wagh Avatar asked Sep 16 '16 07:09

Nilesh Wagh


1 Answers

You should store client specific information in Session instead of Cache. Cache should be for the whole application (shared)

However, it's not recommended as web api is built with RESTful in mind and RESTful services should be stateless (APIs do not cache state). Stateless applications have many benefits:

  • Reduce Memory Usage
  • Better scalability: Your application scales better. Image what happens if you store information of millions of client at the same time.
  • Better in load balancing scenario: every server can handle every client without losing state.
  • Session expiration problem.

In case you want to store client state, you could do it anyway. Please try the suggestions in the following post: ASP.NET Web API session or something?

In general, caching state locally on the web server is bad (both Session and local MemoryCache). The cache could lose for many reasons:

  • App pool recycle.
  • Load balancing environment
  • Multiple worker processes in IIS

Regarding your requirements:

Each client get session information and access list from server for synchronization purpose on every second. According to access changed, client functionality will changed(Enable/Disable).

I'm not sure if you want to update the other clients with new access list immediately when a client sends synchronization call. If that's the case, SignalR would be a better choice.

Otherwise, you could just store the updated access list somewhere (shared cache or even in database) and update the other clients whenever they reconnect with another request.

like image 98
Khanh TO Avatar answered Oct 02 '22 23:10

Khanh TO