Click here to monitor SSC

Caffeine Induced Tirades about .NET and Life

SharePoint 2010 HierarchicalConfig Caching Problem

Published 29 October 2011 4:58 am

We’ve started using the Application Foundations for SharePoint 2010 in some of our projects at work, and I came across a nasty issue with the hierarchical configuration settings.  I have some settings that I am storing at the Farm level, and as I was testing my code it seemed like the settings were not being saved – at least that is what it appeared was the case at first. 

However, I happened to reset IIS and the settings suddenly appeared.  Immediately, I figured that it must be a caching issue and dug into the code base.  I found that there was a 10 second caching mechanism in the SPFarmPropertyBag and the SPWebAppPropertyBag classes.  So I ran another test where I waited 10 seconds to make sure that enough time had passed to force the caching mechanism to reset the data.  After 10 minutes the cache had still not cleared.  After digging a bit further, I found a double lock check that looked a bit off in the GetSettingsStore() method of the SPFarmPropertyBag class:

if (_settingStore == null || 
(DateTime.Now.Subtract(lastLoad).TotalSeconds) > cacheInterval))
{ //Need to exist so don't deadlock. rrLock.EnterWriteLock(); try { //make sure first another thread didn't already load... if (_settingStore == null)
{ _settingStore = WebAppSettingStore.Load(this.webApplication); lastLoad = DateTime.Now; } } finally { rrLock.ExitWriteLock(); } }

What ends up happening here is the outer check determines if the _settingStore is null or the cache has expired, but the inner check is just checking if the _settingStore is null (which is never the case after the first time it’s been loaded).  Ergo, the cached settings are never reset. 

The fix is really easy, just add the cache checking back into the inner if statement.

//make sure first another thread didn't already load...
if (_settingStore == null || 
(DateTime.Now.Subtract(lastLoad).TotalSeconds) > cacheInterval)

{ _settingStore = WebAppSettingStore.Load(this.webApplication); lastLoad = DateTime.Now; }

And then it starts working just fine. as long as you wait at least 10 seconds for the cache to clear.

Leave a Reply