Пример #1
0
        private void SetConstructor(ConstructorCacheKey cacheKey, ConstructorCacheValue previousCacheValue, ConstructorInfo constructorInfo)
        {
            // Currently I choose last-win strategy but maybe other should be used
            _constructorCacheLock.PerformWrite(() =>
            {
                ConstructorCacheValue storedValue;
                if (!_constructorCache.TryGetValue(cacheKey, out storedValue))
                {
                    storedValue = ConstructorCacheValue.First();
                }

                if (storedValue.Version == previousCacheValue.Version)
                {
                    // Log.Debug("Everything is fine");
                }
                else if (storedValue.Version > previousCacheValue.Version)
                {
                    Log.Debug("Data in cache have been changed between read & write.");
                }
                else
                {
                    // TODO: Maybe exception should be thrown
                    Log.Debug("Something strange have happend. Deep log analyze required.");
                }
                // I'm not sure storedValue or previousCacheValue should be passed in here
                var cacheValue = ConstructorCacheValue.Next(storedValue, constructorInfo);
                _constructorCache[cacheKey] = cacheValue;
            });
        }
Пример #2
0
 private ConstructorCacheValue GetConstructor(ConstructorCacheKey cacheKey)
 {
     return(_constructorCacheLock.PerformRead(() =>
     {
         ConstructorCacheValue result;
         if (_constructorCache.TryGetValue(cacheKey, out result))
         {
             return result;
         }
         return ConstructorCacheValue.First();
     }));
 }
Пример #3
0
        /// <summary>
        /// Clears the cache of all constructors.
        /// <para />
        /// This call is normally not necessary since the type factory should keep an eye on the
        /// <see cref="IServiceLocator.TypeRegistered"/> event to invalidate the cache.
        /// </summary>
        public void ClearCache()
        {
            // Note that we don't clear the constructor metadata cache, constructors on types normally don't change during an
            // application lifetime

            // Clear cache isn't really that important, it's better to prevent deadlocks. How can a deadlock occur? If thread x is creating
            // a type and loads an assembly, but thread y is also loading an assembly. Thread x will lock because it's creating the type,
            // thread y will lock because it wants to clear the cache because new types were added. In that case ignore clearing the cache

            // Edit: Probability of loading assembly inside of lock have been drastically reduced so comment above probably isn't relevant
            _constructorCacheLock.PerformWrite(() =>
            {
                var array = _constructorCache.ToArray();
                foreach (var keyValuePair in array)
                {
                    _constructorCache[keyValuePair.Key] = ConstructorCacheValue.Next(keyValuePair.Value, null);
                }
            });

            // This log entry makes sence in optimistic lock scenarios
            Log.Debug("Cleared type constructor cache");
        }
Пример #4
0
 /// <summary>
 /// Creates entry that replaces previous entry in cache for key.
 /// </summary>
 /// <param name="previousValue">Previously used constructor.</param>
 /// <param name="constructorInfo">Creates first entry in cache for key.</param>
 /// <returns></returns>
 public static ConstructorCacheValue Next(ConstructorCacheValue previousValue, ConstructorInfo constructorInfo)
 {
     return(new ConstructorCacheValue(constructorInfo, previousValue.Version + 1));
 }