If you look at the Cache.cs file, you can see that one of the methods takes 3 arguments:
static public void Set(string key, Object data, Int64 dependencykey)
This does some stuff and then calls into a 4 argument Set method that has the timeout as well. Here’s the thing. It looks like some of the code calls this 3 argument Set method correctly, with the 3rd argument being the nodeid of some dependent items. But many places in the code call this thinking that the 3rd argument should be the timeout:
//Defaulted this to be one hour
Framework.Utilities.Cache.Set("GetDivisions", divisions, 3600);
When this happens, the item is never even added to the cache because of the confusion with the dependency key. We use the cache heavily with our OpenSocial ORNG work so that’s how we noticed.
Can someone confirm?
Thanks
Eric
Thanks, we made a fix as well.
I also noticed something else where I could use some verification, and this one had big implications for us:
It seems that .NET will mark any CacheDependency object as HasChanged=TRUE whenever a matching key is added or removed from the cache.
So… on line 50 of Cache.cs we call a method to create a CacheDependency object immediately prior to adding an object to the cache. The CreateDependency method first creates the CacheDependency object, then it adds an appropriate key (and placeholder dummy value) into the cache. When this happens, the CacheDependency object goes from HasChanged=FALSE to HasChanged=TRUE. When the call returns to line 50 in Cache.cs, the HttpRuntime.Cache.Insert method is called but the object is immediately rejected from the cache because of the HasChanged value. So in other words, caching is completely disabled for any item with a dependency.
Fixing the bug might just be a matter of swapping lines 151 and 152 in Cache.cs so that you first add the key, and then create the object. To be safe we did more and also added a check to see if the key is already in the cache:
static public CacheDependency CreateDependency(string key)
{
String[] dependencyKey = new String[1];
dependencyKey[0] = "Node Dependency " + key;
CacheDependency dependency = null;
if (key != "0")
{
if (HttpRuntime.Cache[dependencyKey[0]] == null)
{
HttpRuntime.Cache.Insert(dependencyKey[0], Guid.NewGuid().ToString());
}
dependency = new CacheDependency(null, dependencyKey);
}
return dependency;
}
Eric