Override HttpContext.Current.Cache in Load Balanced Envrionment. - asp.net

We have an environment with a vendor deployed application to several front ends on it. It makes heavy use of the ASP .Net storage (Session, Application, and Cache). Problem is with the load this environment quickly brings IIS to it's knees with the amount of data it's trying to keep in memory.
The solution we are trying to go with is to override the storage mechanism and implement our own. (Specifically a Redis server to manage the storage)
We have implemented their cache interface and set up Microsoft.Web.Redis.RedisSessionStateProvider in the web.config to manage the session. That part all works fine. The problem is that the caching inside the vendor application does not always use their provided interface. Decompiling the dll and examining dump files show that there are several instances of them directly calling (for example):
HttpContext.Current.Cache.Insert(...) and HttpContext.Current.Application[...] = ...
Is there any way we can override the HTTPContext* calls so that they'll use Redis to cache instead of the Asp .Net application storage?

When it is a "3rd" party which uses HttpContext.Current you probably have no chance to change that behavior.
Is this other application running within your context (do you control the app domain). Or is it a standalone application?
I once tried to change HttpContext.Current.Cache for unit testing and ended up mocking the whole HttpContext because it was so very internal somewhere in the Microsoft stack.
All this is pretty hard to do, not really recommended and can lead to all kinds of other errors.
In short, don't use HttpContext.Current.Cache. Use something you can inject.
In general, libraries should never use that static context.
It is much more flexible to have abstractions + DI for those kind of things...
For caching, you could use CacheManager for example.

Related

How to inject/handle usage of HttpContex.Cache

I have a legacy application that is extensively using HttpContext.Cache...
This application is now suppose to move to Windows Azure (multi-role).
It will of course cause problems with cache going out of sync on different roles.
I was thinking about injecting (I'm using Autofac) my "AzureCacheWrapper" (wrapper on Microsoft.ApplicationServer.Caching.DataCache) into HttpContext.Cache so legacy application continues working but uses Azure cache instead?
Normally we should implement something like ICacheProvider but unfortunately there are some 3rd party DLLs that are using cache that we don't have access to (and don't know when 3rd party library is using Http cache)
I don't think cache provider can be configured through web.config (like OutputCaching) so the only solution seems to me to somehow inject my implementation into Add/Insert/Get methods on Runtime Cache.
Unfortunately because of .NET implementation of System.Web.Caching.Cache (sealed class) I don't think I can override HttpContextBase to return different cache or inject into System.Web.Caching.Cache itself...
Thanks for any help! :)
I think your application needs code/architectural change...
If you had your own class which handles getting and setting the cache, Which may easier now to change your code/architecture in one place.
If you are going to use Single role then no problem exist in your scinario. If possible you can run your webrole in ExtraLarge slot.

API in Symfony and caching

I'm building a site in Symfony 2.0 that has a fair amount of AJAX, which builds page content with data it gets from an API, like: http://mysite.com/api/pictures/list
Data is handled using Repositories, which are sometimes used in page code so that string of images you see might come from the controller using the PictureRepository, or via Ajax using the API which accesses the PictureRepository.
I'd like to use Memcached to ease the database load, but am not sure where to put the caching code. Is it best to cache the database result, or the API result? Or is the difference negligible? Having the memcached logic inside the Repository would mean writing the code once (regardless of whether it's accessed via the API or directly), but it seems like it would also make sense to avoid accessing the Repository whenever possible.
Thoughts?
My opinion is that memcached should be used for session storage.
For your purposes you should better think about using of Varnish as http cache.
After that, you can configure your application use ESI.
At least, that is how we do it in our applications ;)

Can I switch out .Net cache provider through configuration

Is there a way in .Net to switch out the Cache provider just like I would a membership provider, or role provider? I would like to keep the code untouched but switch to using a distributed cache like memcached or AppFabric.
All I am finding is how to switch out the output cache provider. This might be necessary, but it doesn't solve the issue of when Cache is called directly from within my code.
I've found many libraries and they abstract Cache behind an interface, but this would mean I have to go to every spot in my code and inject the new abstraction. Also I am using PLINQO, which internally uses Cache.
Is OutputCache the only thing I can switch out through configuration?
Thank you in advance.
You may take a look at the following presentation which explains the pre-.NET 4.0 state of caching and what .NET 4.0 brings in this respect. In .NET 4.0 the caching has been completely reworked into a separate assembly (System.Runtime.Caching) and rendered extensible. That's true for both object caching and page output caching. Unfortunately if you have current code that relies on the old Cache class this has to be changed as this class works with in-memory objects only.

SpecFlow, Webdriver and Mocks - is it possible?

The question in short is that we are stumbling upon BDD definitions that more or less require different states - which leads to the necessity for a mock of sorts for ASP.NET/MVC - I know of none, which is why I ask here
Details:
We are developing a project in ASP.NET (MVC3/Razor engine) and are using SpecFlow to drive our development.
We quite often stumble into situations where we need the webpage under test to perform in a certain manner so that we can verify the behavior, i.e:
Scenario: Should render alternatively when backend system is down
Given that the backend system is down
And there are no channels for the page to display
When I inspect the webpage under test
Then the page renderes an alternative html indicating that there is a problem
For a unit test, this is less of an issue - run mock on the controller bit, and verify that it delivers the correct results, however, for a SpecFlow test, this is more or less requiring alternate configurations.
So it is possible at all, or - are there some known software patterns for developing webpages using BDD that I've missed?
Even when using SpecFlow, you can still use a mocking framework. What I would do is use the [BeforeScenario] attribute to set up the mocks for the test e.g.
[BeforeScenario]
public void BeforeShouldRenderAlternatively()
{
// Do mock setups.
}
This SO question might come in handy for you also.
You could use Deleporter
Deleporter is a little .NET library that teleports arbitrary delegates into an ASP.NET application in some other process (e.g., hosted in IIS) and runs them there.
It lets you delve into a remote ASP.NET application’s internals without any special cooperation from the remote app, and then you can do any of the following:
Cross-process mocking, by combining it with any mocking tool. For example, you could inject a temporary mock database or simulate the passing of time (e.g., if your integration tests want to specify what happens after 30 days or whatever)
Test different configurations, by writing to static properties in the remote ASP.NET appdomain or using the ConfigurationManager API to edit its entries.
Run teardown or cleanup logic such as flushing caches. For example, recently I needed to restore a SQL database to a known state after each test in the suite. The trouble was that ASP.NET connection pool was still holding open connections on the old database, causing connection errors. I resolved this easily by using Deleporter to issue a SqlConnection.ClearAllPools() command in the remote appdomain – the ASP.NET app under test didn’t need to know anything about it.

IOC Containers and Web applications

I have started to work on this .NET web application where it has an IOC container (Windsor) to create business managers, and to keep them in the memory until the IIS recycles them. Basically these business managers are having their own states, and data of which the content is modified from background threads that are fired at the Application_Start . This is not the way I was expecting an web application to work ( which are supposed to be stateless and per thread for per request) and I'm not quite sure if this implementation is sustainable/scalable. Has anybody tried the things in this manner if so what are the consequences/pros that you see in this?
We use statics in the application, only for the core features. Static classes are shared across all the requests, so usability should be somewhat low. In the development world, we're seeing statics pop up more and more: ASP.NET MVC 3 utilizes them for various areas of the application, as well as other popular OS source libraries.
As long as there aren't a lot of them, you should be OK... but you can always verify with a memory profiler too see how big they are getting, and whether they are sucking up too much memory.
The other alternative could be to place them in cache, or rebuild them and store them in each request. To store them globally in a request, use HttpContext.Current.Items collection.

Resources