private void IncFailCount(string resourceKey) { object countObj; if (!_failCountCache.AddIfNotExists(resourceKey, 1, failCountTimeout, null, null, out countObj)) { if (countObj is int) { _failCountCache.Insert(resourceKey, (int)countObj + 1, failCountTimeout, null, null); } } }
/// <summary> /// Execute any function without parameters and return defined type of result. /// </summary> /// <typeparam name="TResult">Return type.</typeparam> /// <param name="key">The string key of the item.</param> /// <param name="methodToCall">The method that is called to fetch data.</param> /// <param name="defaultResult">If cache fetching and methodToCall fails to return data return this value.</param> /// <param name="timeout">The time to store data in the cache before a new fetch is done.</param> /// <param name="cacheKeys">The dependencies to other cached items, idetified by their keys.</param> /// <param name="masterKeys">The master keys that we depend upon. Master keys are used as markers to set up common dependencies without having to create the cache entries first.</param> /// <param name="resourceKey">Resource name used in Disable() call.</param> /// <returns>TResult type defined in the call.</returns> public TResult ExecuteAndCache <TResult>(string key, List <string> cacheKeys, List <string> masterKeys, Func <TResult> methodToCall, TResult defaultResult, TimeSpan timeout, string resourceKey) { TResult cachedResult; bool manuallyDisabled; if (ResourceIsDisabled(resourceKey, out manuallyDisabled)) { if (manuallyDisabled) { return(defaultResult); } return(GetCachedOrDefault(key, _dataCache, defaultResult)); } // Check for fast return, first check if value has timed out if (_dataTimeoutCache.Get(key) != null) { if (TryGetCached(key, _dataCache, out cachedResult)) { return(cachedResult); } } // Cache has timed out. First mark that fetching is in progress if (_fetchFlagCache.AddIfNotExists(key, 1, execTimeout, cacheKeys, masterKeys)) { try { try { // Fetch new value var newValue = methodToCall(); _dataCache.Insert(key, newValue, new TimeSpan(timeout.Ticks + Math.Max(timeout.Ticks, oldDataMaxTimeout.Ticks)), cacheKeys, masterKeys); _dataTimeoutCache.Insert(key, 1, timeout, cacheKeys, masterKeys); return(newValue); } catch (Exception e) { Log.Error("Failed to execute on resource: " + resourceKey, e); IncFailCount(resourceKey); if (ResourceIsDisabled(resourceKey)) { Log.ErrorFormat("Resource {0} is auto disabled for {1} seconds.", resourceKey, failCountTimeout.TotalSeconds); } // Remove timeout item because no new data was stored. _dataTimeoutCache.Remove(key); // Something went wrong return default return(defaultResult); } } finally { _fetchFlagCache.Remove(key); } } // The fetching is already in progress, return existing data if (TryGetCachedWithWait(key, _dataCache, out cachedResult)) { return(cachedResult); } return(defaultResult); }