/// <summary> /// Bir global jenerasyonu arttırarak, bu global jenerasyon koduna sahip tüm item ların expire olmasını sağlar. /// </summary> /// <param name="globalGenerationKey"></param> public static void ChangeGlobalGeneration(string globalGenerationKey) { HttpRuntime.Cache.Remove(globalGenerationKey); DistributedCache.Set <object>(globalGenerationKey, null); }
/// <summary> /// Changes a group generation value, so that all items that depend on it are expired. /// </summary> /// <param name="groupKey">Group key</param> public static void ExpireGroupItems(string groupKey) { LocalCache.Provider.Remove(groupKey); DistributedCache.Set <object>(groupKey, null); }
/// <summary> /// Bir değeri varsa yerel cache'ten yoksa distributed cache'ten o da yoksa verilen fonksiyonu çağırarak getirir. /// Veri, gerek local cache'te, gerekse distributed cache'te belirtilen "expiration" süresince saklanır. /// Ancak, "globalGenerationKey" ile belirtilen bir versiyonlama keyi kullanılarak, distributed cache'te /// bu jenerasyon değiştiğinde, gerek distributed cache'te gerekse local cache'te bulunan tüm item lar /// expire edilebilir. Bu jenerasyon bilgisini sürekli kontrol etmemek için de performans açısından 1 dk boyunca versiyon /// bilgisi de cache lenir. Yani versiyon değiştiğinde, distributed cache resetlendiğinde, local cache ler bundan 1 dk sonra /// haberdar olur. /// </summary> /// <typeparam name="TItem">Cache ten getirilecek objenin tipi</typeparam> /// <typeparam name="TSerialized">Objenin distributed cache e gönderilmeden önce serialize edileceği tip (performans açısından byte[] ya da string olmalı)</typeparam> /// <param name="cacheKey">Hem local hem de distributed cache için kullanılacak item key i</param> /// <param name="expiration">Hem local hem de distributed cache için kullanılacak expiration</param> /// <param name="globalGenerationKey">Global versiyon numarasının kontrol edileceği key. Bu tablo adı olabilir mesela. Bu key arttırılarak /// tüm cache lerin yenilenmesi sağlanabilir.</param> /// <param name="loader">Hiçbir cache te item bulunamazsa yüklemeyi yapacak delegate</param> /// <param name="serialize">Veriyi distributed cache e gönderilmeden serialize edecek fonksiyon</param> /// <param name="deserialize">Veriyi distributed cache ten getirdikten sonra deserialize edecek fonksiyon</param> /// <returns></returns> private static TItem GetInternal <TItem, TSerialized>(string cacheKey, TimeSpan localExpiration, TimeSpan remoteExpiration, string globalGenerationKey, Func <TItem> loader, Func <TItem, TSerialized> serialize, Func <TSerialized, TItem> deserialize) where TItem : class where TSerialized : class { ulong?globalGeneration = null; ulong?globalGenerationCache = null; // local cache ve dist cache te bir item ın versiyon bilgisini tutmak için kullanacağımız key string itemGenerationKey = cacheKey + GenerationSuffix; // lazy şekilde distributed cache teki global versiyon numarasını getirir Func <ulong> getGlobalGenerationValue = delegate() { if (globalGeneration != null) { return(globalGeneration.Value); } globalGeneration = DistributedCache.Get <ulong?>(globalGenerationKey); if (globalGeneration == null || globalGeneration == 0) { globalGeneration = RandomGeneration(); DistributedCache.Set(globalGenerationKey, globalGeneration.Value); } globalGenerationCache = globalGeneration.Value; // local cache e ekle, 1 dk boyunca buradan kullan LocalCache.AddToCacheWithExpiration(globalGenerationKey, globalGenerationCache, GenerationCacheExpiration); return(globalGeneration.Value); }; // lazy şekilde local cache teki global versiyon numarasını getirir Func <ulong> getGlobalGenerationCacheValue = delegate() { if (globalGenerationCache != null) { return(globalGenerationCache.Value); } // global jenerasyonın local de cache lediğimiz değerine bak (1 dk da bir cache ten silinir, server dan sorarız) globalGenerationCache = HttpRuntime.Cache.Get(globalGenerationKey) as ulong?; // cache te varsa onu döndür if (globalGenerationCache != null) { return(globalGenerationCache.Value); } return(getGlobalGenerationValue()); }; // öncelikle local cache'e bak, varsa ve expire olmadıysa (global versiyon artışı nedeniyle) döndür var cachedObj = HttpRuntime.Cache.Get(cacheKey); if (cachedObj != null) { // önce local cache'e bak, varsa bununla global versiyonu karşılaştır var itemGenerationCache = HttpRuntime.Cache.Get(itemGenerationKey) as ulong?; if (itemGenerationCache != null && itemGenerationCache == getGlobalGenerationCacheValue()) { // local cache imizdeki item henüz expire olmamış if (cachedObj == DBNull.Value) { return(null); } return((TItem)cachedObj); } // local cache teki item expire olmuş, tüm bilgilerini temizle if (itemGenerationCache != null) { HttpRuntime.Cache.Remove(itemGenerationKey); } HttpRuntime.Cache.Remove(cacheKey); cachedObj = null; } // serialize null ise bu dist cache te saklanmayacak, sadece local de tutulacak demektir if (serialize != null) { // local cache te item yok ya da expire olmuştu, şimdi dist cache i sorgulayalım var itemGeneration = DistributedCache.Get <ulong?>(itemGenerationKey); // item ın dist cache te versiyonu varsa, bu global versiyonla eşitse if (itemGeneration != null && itemGeneration.Value == getGlobalGenerationValue()) { // distributed cache ten item ı al var serialized = DistributedCache.Get <TSerialized>(cacheKey); // eğer distributed cache te item da var ise if (serialized != null) { cachedObj = deserialize(serialized); LocalCache.AddToCacheWithExpiration(cacheKey, (object)cachedObj ?? DBNull.Value, localExpiration); LocalCache.AddToCacheWithExpiration(itemGenerationKey, getGlobalGenerationValue(), localExpiration); return((TItem)cachedObj); } } } // ne local ne dist cache te geçerli bir sürüm bulamadık, normal item ı ürettir var item = loader(); // item ı ve jenerasyonunu local cache e yaz LocalCache.AddToCacheWithExpiration(cacheKey, (object)item ?? DBNull.Value, localExpiration); LocalCache.AddToCacheWithExpiration(itemGenerationKey, getGlobalGenerationValue(), localExpiration); if (serialize != null) { var serializedItem = serialize(item); // item ı ve jenerasyonunu dist cache e yaz if (remoteExpiration == CacheExpiration.Never) { DistributedCache.Set(cacheKey, serializedItem); DistributedCache.Set(itemGenerationKey, getGlobalGenerationValue()); } else { DistributedCache.Set(cacheKey, serializedItem, DateTime.Now.Add(remoteExpiration)); DistributedCache.Set(itemGenerationKey, getGlobalGenerationValue(), DateTime.Now.Add(remoteExpiration)); } } return(item); }
/// <summary> /// Changes a group generation value, so that all items that depend on it are expired. /// </summary> /// <param name="groupKey">Group key</param> public static void ExpireGroupItems(string groupKey) { Dependency.Resolve <ILocalCache>().Remove(groupKey); DistributedCache.Set <object>(groupKey, null); }