Cache dependency on other items

Topics: Caching Application Block
Jan 20, 2010 at 10:21 AM

Looking to the various cache expiration policies that are possible I was missing a cache expiration that depends on other items in the cache; it is not present in the Microsoft.Practices.EnterpriseLibrary.Caching.Expirations namespace. I tried to implement something myself, but discovered the ICacheManager has no notification interface at all (why not?). Therefore I tried creating a Microsoft.Practices.EnterpriseLibrary.Caching.Cache instance myself passing a Microsoft.Practices.EnterpriseLibrary.Caching.Instrumentation.CachingInstrumentationProvider instance, and to listen to the cacheExpired event as following:

Microsoft.Practices.EnterpriseLibrary.Caching.Instrumentation.CachingInstrumentationProvider itemsCacheInstrumentationProvider = new Microsoft.Practices.EnterpriseLibrary.Caching.Instrumentation.CachingInstrumentationProvider();
itemsCacheInstrumentationProvider.cacheExpired += new EventHandler<Microsoft.Practices.EnterpriseLibrary.Caching.Instrumentation.CacheExpiredEventArgs>(itemsCacheInstrumentationProvider_cacheExpired);

Microsoft.Practices.EnterpriseLibrary.Caching.Cache itemCache = new Microsoft.Practices.EnterpriseLibrary.Caching.Cache(
	new Microsoft.Practices.EnterpriseLibrary.Caching.BackingStoreImplementations.NullBackingStore(),
	new CacheCapacityScavengingPolicy(1000),
	itemsCacheInstrumentationProvider
);
However, the cacheExpired event does not pass any information about the items expired with it (Microsoft.Practices.EnterpriseLibrary.Caching.Instrumentation.CacheExpiredEventArgs only contains a count how much items expired). Any suggestions how I can achieve a cache dependency on other cached items?

Jan 21, 2010 at 2:18 AM

There is an overload in the Add method which allows you to specify an instance of ICacheItemRefreshAction.  It has only one method (Refresh) which serves as a notification that an item has expired and the key and actual value of that item.  As for the kind of dependency you want, you would need to implement your own ICacheItemExpiration.

So in summary, you would need to implement your own ICacheItemRefreshAction and ICacheItemExpiration.  You need not create your own Cache.

 

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com 

Jan 21, 2010 at 3:41 PM
The problem is that I want to add a cache dependency runtime when I add new items to the cache. For example, there may be an object X in the cache, to which I want to add a dependency when loading and caching the object Y depending on X.

(That is not possible unless I add watcher instances to every cache item beforehand, bookkeep these watcher instances myself (in some dictionary) to add new watcher listeners runtime...)



On Thu, Jan 21, 2010 at 3:18 AM, AvanadeSupport <notifications@codeplex.com> wrote:

From: AvanadeSupport

There is an overload in the Add method which allows you to specify an instance of ICacheItemRefreshAction.  It has only one method (Refresh) which serves as a notification that an item has expired and the key and actual value of that item.  As for the kind of dependency you want, you would need to implement your own ICacheItemExpiration.

So in summary, you would need to implement your own ICacheItemRefreshAction and ICacheItemExpiration.  You need not create your own Cache.

 

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com 

Read the full discussion online.

To add a post to this discussion, reply to this email (entlib@discussions.codeplex.com)

To start a new discussion for this project, email entlib@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on CodePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at CodePlex.com


Jan 25, 2010 at 4:28 AM

I'm still not clear why the ICacheItemRefreshAction won't work for you.  What exactly is the dependency between your cache items?

 

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com 

Jan 25, 2010 at 8:54 AM
OK, here is an example:

Scenario 1:
Suppose my cache is empty at the beginning. Suppose some item X is requested first. X will be added to the cache, without any ICacheItemRefreshAction.
Suppose some item Y is requested after that. Suppose Y depends on X, such that if X expires, Y expires too. Y will be added to the cache. HOWEVER, there is no possibility to add a ICacheItemRefreshAction to X now. Therefore, this scenario cannot work for me.

Scenario 2:
Suppose my cache is empty at the beginning. Suppose some item X is requested first. X will be added to the cache, WITH a ICacheItemRefreshAction because other items MAY depend on X. I need a custom implementation of ICacheItemRefreshAction such as:
class CacheItemDependencyRefreshAction : ICacheItemRefreshAction
{
ICacheManager dependingCache;
List<string> dependingItems;

public CacheItemDependencyRefreshAction(ICacheManager dependingCache)
{
this.dependingCache = dependingCache;
this.dependingItems = new List<string>();
}

public void AddDependencyItem(string key)
{
this.dependingItems.Add(key);
}

#region ICacheItemRefreshAction Members

          public void Refresh(string removedKey, object expiredValue, CacheItemRemovedReason removalReason)
          {
            foreach (string dependingItem in this.dependingItems)
            {
            this.dependingCache.Remove(dependingItem);
            }
          }

          #endregion
}
Suppose some item Y is requested after that. Suppose Y depends on X, such that if X expires, Y expires too. Y will be added to the cache. HOWEVER, I need the CacheItemDependencyRefreshAction instance I created for X to add the dependency to X. Therefore, I need to add a Dictionary<string, CacheItemDependencyRefreshAction> cacheItemRefreshActions to be able to add the dependency to X:

cacheItemRefreshActions[dependedItemKey].AddDependencyItem(dependingItemKey);

BUT that is not nice because I have to maintain this dictionary myself: I would have to remove a CacheItemDependencyRefreshAction when a cache item is removed. Moreover, the CacheItemDependencyRefreshAction instances would have to listen to item removal itself to keep the dependingItems collection up to date (that is, remove an item when it is removed from the cache)!




On Mon, Jan 25, 2010 at 5:28 AM, AvanadeSupport <notifications@codeplex.com> wrote:

From: AvanadeSupport

I'm still not clear why the ICacheItemRefreshAction won't work for you.  What exactly is the dependency between your cache items?

 

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com 

Read the full discussion online.

To add a post to this discussion, reply to this email (entlib@discussions.codeplex.com)

To start a new discussion for this project, email entlib@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on CodePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at CodePlex.com


Jan 25, 2010 at 9:24 AM

How about this: 

Implement your own ICacheItemExpiration, something like this one:

public class AnotherCacheItemExpiration : ICacheItemExpiration
    {
        string cacheItemKey = null;

        public AnotherCacheItemExpiration(string cacheDependencyKey)
        {
            cacheItemKey = cacheDependencyKey;
        }

        #region ICacheItemExpiration Members

        public bool HasExpired()
        {
            object dependency = CacheFactory.GetCacheManager().GetData(cacheItemKey);
            if (dependency != null)
            {
                return false;
            }
            return true;
        }

        public void Initialize(CacheItem owningCacheItem)
        {
          
        }

        public void Notify()
        {
           
        }

        #endregion
    }

You can add x without any extra parameters for ICacheItemExpiration or ICacheItemRefreshAction.  And then if you want to add y with dependency on x, add it passing an instance of AnotherCacheItemExpiration where in the cacheDependencyKey parameter is the value of x's cache key.  When x expires, so does y.  If you're dependency is just like as you stated, one expires if the dependency does, you no longer need to have your own ICacheItemRefreshAction.  You usually need it if you need to perform extra logic when an item expires.

 

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com  

Jan 25, 2010 at 3:08 PM
Thank you for the suggestion. I think that solves my problem :).


On Mon, Jan 25, 2010 at 10:24 AM, AvanadeSupport <notifications@codeplex.com> wrote:

From: AvanadeSupport

How about this: 

Implement your own ICacheItemExpiration, something like this one:

public class AnotherCacheItemExpiration : ICacheItemExpiration
    {
        string cacheItemKey = null;

        public AnotherCacheItemExpiration(string cacheDependencyKey)
        {
            cacheItemKey = cacheDependencyKey;
        }

        #region ICacheItemExpiration Members

        public bool HasExpired()
        {
            object dependency = CacheFactory.GetCacheManager().GetData(cacheItemKey);
            if (dependency != null)
            {
                return false;
            }
            return true;
        }

        public void Initialize(CacheItem owningCacheItem)
        {
          
        }

        public void Notify()
        {
           
        }

        #endregion
    }

You can add x without any extra parameters for ICacheItemExpiration or ICacheItemRefreshAction.  And then if you want to add y with dependency on x, add it passing an instance of AnotherCacheItemExpiration where in the cacheDependencyKey parameter is the value of x's cache key.  When x expires, so does y.  If you're dependency is just like as you stated, one expires if the dependency does, you no longer need to have your own ICacheItemRefreshAction.  You usually need it if you need to perform extra logic when an item expires.

 

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com  

Read the full discussion online.

To add a post to this discussion, reply to this email (entlib@discussions.codeplex.com)

To start a new discussion for this project, email entlib@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on CodePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at CodePlex.com