Caching application data in memory: MVC Web API - c#

I am writing an MVC webAPI that will be used to return values that will be bound to dropdown boxes or used as type-ahead textbox results on a website, and I want to cache values in memory so that I do not need to perform database requests every time the API is hit.
I am going to use the MemoryCache class and I know I can populate the cache when the first request comes in but I don't want the first request to the API to be slower than others. My question is: Is there a way for me to automatically populate the cache when the WebAPI first starts? I see there is an "App_Start" folder, maybe I just throw something in here?
After the initial population, I will probably run an hourly/daily request to update the cache as required.
MemoryCache:
http://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache.aspx
UDPATE
Ela's answer below did the trick, basically I just needed to look at the abilities of Global.asax.
Thanks for the quick help here, this has spun up a separate question for me about the pros/cons of different caching types.
Pros/Cons of different ASP.NET Caching Options

You can use the global.asax appplication start method to initialize resources.
Resources which will be used application wide basically.
The following link should help you to find more information:
http://www.asp.net/web-forms/tutorials/data-access/caching-data/caching-data-at-application-startup-cs
Hint:
If you use in process caching (which is usually the case if you cache something within the web context / thread), keep in mind that your web application is controlled by IIS.
The standard IIS configuration will shut down your web application after 20 minutes if no user requests have to be served.
This means, that any resources you have in memory, will be freed.
After this happens, the next time a user accesses your web application, the global asax, application start will be excecuted again, because IIS reinitializes your web application.
If you want to prevent this behaviour, you either configure the application pool idle timeout to not time out after 20minutes. Or you use a different cache strategy (persistent cache, distributed cache...).
To configure IIS for this, here you can find more information:
http://brad.kingsleyblog.com/IIS7-Application-Pool-Idle-Time-out-Settings/

Related

OutputCache of .NET MVC5 App in Azure Falls Out of Cache Quickly

My Goal: Cache basically all the pages all the time so that users rarely ever have to hit my CMS for content.
I have a c#/.Net MVC 5 Web App deployed in Azure. I also have all the OutputCache's on my controllers set for 1 week [604800s] (content rarely changes). I assume, maybe naively, that the cached outputs are stored in memory in Azure. However, when I start my app and crawl the website, I'd expect the Azure memory to fill up with cached content, but in practice, there might be a bump in memory utilization. It goes back to its "resting state" of like 60% utilization after about 5 mins, though. I've also tried using MemoryCache, but it has a similar result - a bump in memory usage, and it goes down to normal shortly after.
In any case, the result is that the pages act like they weren't cached. For example, if I crawl 1 page and visit it - it loads in about 1 second (it's cached). If i crawl 2000 pages and visit a random one, it loads in 3-4 seconds (it's not cached). I've tested this by putting a datetime in the view itself.
So... the bottom line is: cached = fast, not cached = average. I want it to be fast!
I've looked at Redis Cache, which could be a way to do this, and seems easy enough... but my gut says this should be basic functionality (since it's built into the framework).
Azure Web App did support in-memory OutputCache. We can easily confirm it using following code. The output datetime will not be changed after you refresh the TestCache page.
[OutputCache(Duration = 3600)]
public ActionResult TestCache()
{
return Content(DateTime.Now.ToString());
}
But there are some problems when using in-memory cache in Azure Web App.
First problem with this is that it limits you to the memory that is available on your web app instance and this may create an out of memory issue when you cache a large amount of page output data. Your web app will be restarted if your memory is full. If the web app is restart, all the cached content will be lost. Another issue is that your application runs on multiple load balanced instances. The next request might go to another instance, which creates a new copy of ASP.NET Output Cache data in this instance, as well. These redundant copies of page outputs in each Web Role instance consume a lot of extra memory.
To avoid the upper problems, I suggest you use Redis Cache to store the cached content. For how to use Redis Cache, link below is for your reference.
ASP.NET Output Cache Provider for Azure Redis Cache

How to disable/release early Session-state blocking for long-running Ajax requests in Web Form projects

I'm meeting a problem regarding session-state blocking in ASP.NET web page.
Normally, web-api projects don't have session state. However, as we develop from a legacy projects, web-api 2 module is injected to the old web-form project, and we proceed from there. However, now we detect 2 problems:
The AJAX requests always queue and execute one-by-one. It beats
the purpose of concurrent processing
For long-processing requests,
the user cannot move on another page, even if he/she doesn't need to
know the request result.
The culprit for (1) and (2) is session state blocking. We save authentication information into session state for the web-form projects; and then reuse them on the Web-API controllers. However, as any requests requiring the session, then they execute one-by-one, and for long requests, new request cannot come in even if the user already leave that page (the session is still blocked)
I have checked several answers from related issues, and it seems I'm not alone:
This question informs about the situation clearly, however didn't provide a clear solution (for Web-API case)
This question also give good advises about using Read-only session which does not block concurrency. However, we still not find out how to do with WebAPI controllers inside Web-form project.
According to MVC documents, we can disable session state by adding attribute [System.Web.Mvc.SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)] on controllers' level. However it didn't work (as expected, because we have here Web-API controllers). Unfortunately, I didn't find similar attributes/any mechanism for web-api controllers.
I also check: in PHP case, they have the same issue, yet they can release the session lock early if they want to.
Therefore I'm wondering:
Is there a way to disable session for certain Web-API actions/controllers?
Is there a way to release the lock on session early, when we don't need it any more?
Dot Net serializes session state by default. You can decorate your class with a session modifier so that it can be accessed asynchronously without session state.
This works in cases where the client is java or jquery and they are polling your controller. The controller will release later than sooner. To make it more predictable place this specified on your class:
[SessionState(SessionStateBehavior.ReadOnly)]
function Do()
{
}

Multi-threading and asychronous action call calls With ASP.NET MVC

I am working on a ASP.NET MVC project that should be implement a multi-threading functionality. In fact, in this application, a user can navigate from a page to an other, so he can change the action of his current controller. My question is, Is there a way in ASP.NET MVC that can guarantee that the action is running in background, even though the user has switched the action. It means that even when he returns to the View after he navigates, he can get what he has launched in his current session (knowing that it may take a bit of time in order to do it).I know that it is contradictory with the MVC pattern, but this application should be a server side application.
I did some research and they say that a thread pool and asychronous controllers (http://msdn.microsoft.com/en-us/library/ee728598%28v=vs.100%29.aspx#performing_multiple_operations_in_parallel) may be a solution to this problem. I will be glad to hear any other suggestions to help me implement this project in the right way.
I think you should re-visit the premise that this should be implementing a parallel pattern.
For this to work the way I think you want it to, you will need a shared cache keyed by session id's. Your asynchronous tasks will be storing their results there. You will need some middleware that is initialized when the app initializes, this middleware would consist of a managed thread pool and a buffered queue of tasks. Your UI threads/web server threads would queue a task for the middleware to handle and dump the results in the shared cache which you would then check for results on subsequent web requests from that client. That's a lot of work. Especially if your client and server side applications are already intimately tied together as they usually are in ASP.NET.
Or, you could move the application away from ASP.NET and implement the server side application as a REST API in C# that your client application, written in Javascript, would hit using ajax requests. You build the client app as a single page app in some js MVC framework. This will allow the user to the client app in a seamless experience as calls to the server are non-blocking unless the client app wants them to be. Then there's really no need for the asynchronous patterns you mentioned above, which, honestly are not going to give you any sort of performance gains and it's not going to scale well.

Does an asp.net web-server run a new instance of a web application per request?

I have a web application with private/protected methods or private/protected variables
First I would like to know when a web-server has a connection established already for a certain web application and then receives a new connection does it run a new instance of the web application for this new connection and thus re-initializing all the variables in that web application just like on a computer?
I have goggled the Internet and I am terribly confused!
Second I am using the visual studio development server and I have learned that it doesn't accept connections from other computers, I have gotten around this by using a port forwarding software. So the question is, By doing this does VS2010 web-server see each different requests as a new request or same request since am forwarding them from an app on the local computer?
Finally if I have a web application open on one browser and then decide to open it on another browser and keep the current browser open is this treated as a new request or a post-back?
The app domain is constant (can be recycled) and is created only on the first request (also can be set before that).
That is to say all the static variables are initialized only once
but all the not static classes on which your request depends are initialized on every request.
So basically all your pages in normal asp.net and all the controllers in asp.net MVC are initialized on every request.
read more about it here http://www.codeproject.com/Articles/73728/ASP-NET-Application-and-Page-Life-Cycle
*note - the image has been take from the article referred above
Its a little more complicated than that. The process is optimised for mutiple connections and is stateless, however cashing can be used to imporve scalabilty: That which does not need to be reprocessed can simply be reused: http://www.dotnetfunda.com/articles/article821-beginners-guide-how-iis-process-aspnet-request.aspx is a good place to start understanding what can go on http://msdn.microsoft.com/en-us/library/bb470252%28v=vs.100%29.aspx is a somewhat dryer ms version "iis asp page life cycle" is a good google
The web application instance handles many many requests. And shared state (cache etc) is used very effectively across those requests, whether for a single session or multiple concurrent sessions.
When a request is made, the request object (and any "page" / "controller" object) is created for that request. The state of this object is fresh, but systems like "session state", "view state", cookies, and request values can be used to repopulate it - sometimes largely automated.
A single user making separate requests is not a post-back. They are separate sessions, but even a single session that opens the same page twice (tabs, etc) is not a post-back. It mainly depends on the http verb and other evidences to determine a post-back.
You've got to read this great article: https://lowleveldesign.org/2011/07/20/global-asax-in-asp-net/ for your question. Though it's a little late, it may help others out.

How do I implement shared state in an ASP.NET MVC 3 application?

I'm writing a basic RESTful service, and decided I'd use ASP.NET MVC 3 for the task. My application is going to be responsible for maintaining a persistent connection to a server per user (for now). I had assumed that Application_Start is the place to register static/shared state (like persistent connections), but after reading the documentation for Unity.MVC3, it appears that each request/response cycle will trigger the creation of services (by calling Application_Start).
The documentation I refer to says:
On every request, one UpperCaseService, one LowerCaseService and one ExampleContext are instantiated by DependencyResolver via Unity. At the end of the request, the ExampleContext is automatically disposed
After reading other documentation, and from what I already assumed, Application_Start would be called per AppDomain spawned (again assumed that this would be in the vicinity of how many cores there are on the server).
So, what would be an effective way of maintaining a set of persistent connections to a server, that survive the request/response phase, and if possible, are shared between all AppDomains that the IIS server has created?
It might help to mention that this web service is only going to be consumed by another web site. It is essentially an Authentication Proxy server, however, in the future, it is going to do a lot more. Therefore, I can't just cache the response, as future requests will be required, and reauthenticating is not an option.
If you want to survive AppDomain restarts and share state between multiple ASP.NET applications you will have to go out of the IIS process and store this in a central location that is accessible from all applications. A database is a good candidate.

Categories

Resources