2

I have my website code on two servers and I want a shared cache between them, so I am using Microsoft AppFabric. I only ever want there to be one item in the cache -- not one item per site visitor, just one item total.

The code I'm using to try to accomplish this is below, however, it is not working the way I want it to. I think the problem is that there are many items in the cache, despite them all having the same key. But it could be something else that's happening. See the code comments for more details.

In Web.config:

<dataCacheClient>
    <hosts>
      <host name="MyHost1" cachePort="22233"/>
      <host name="MyHost2" cachePort="22233"/>
    </hosts>
    <securityProperties mode="None" protectionLevel="None" />
</dataCacheClient>
...
<system.web>
    <sessionState mode="InProc" customProvider="AppFabricCacheSessionStoreProvider">
        <providers>
            <add
                name="AppFabricCacheSessionStoreProvider"
                type="Microsoft.ApplicationServer.Caching.DataCacheSessionStoreProvider"
                cacheName="MyCache"
                sharedId="MySharedApp"/>
        </providers>
    </sessionState>
    ...
</system.web>

In Global.asax.cs:

private static DataCacheFactory _cacheFactory = new DataCacheFactory();
private static DataCache _cache;

private void RegisterCacheEntry(){
    try
    {
        // Set up cache
        _cache = _cacheFactory.GetCache("MyCache");

        // Prevent duplicate key addition
        if (_cache.GetCacheItem(CacheItemKey) != null || _cache.Get(CacheItemKey) != null) 
            return;

        // Add item to cache
        _cache.Add(CacheItemKey, CacheItem, TimeSpan.FromMinutes(10));

        // When the cache item is removed, the callback:
        // 1) sends me an email 
        // 2) adds the same item with the same key to the cache again.
        // So I SHOULD be getting one email every 10 minutes.
        // However, it starts with one, but the number of emails that I get increases every 10 minutes.
        // i.e., I get one email at time t=0, two emails at t=1, three at t=2, then four, etc.
        _cache.AddItemLevelCallback(CacheItemKey, DataCacheOperations.RemoveItem, CacheItemRemovedCallback);
    }
    catch (Exception e){}
}

If you want more information on what I'm doing and why, I'm trying to simulate a Windows Service using cache timeout as described here. But I'm trying to get this to work on two servers.

Kalina
  • 5,504
  • 16
  • 64
  • 101

1 Answers1

1

You added AppFabric Session State Provider in web.config. All sessions will be persisted in the cluster : that's why you have multiple cache items.

Also, you will need to add an extra error management in your system, as said here :

Cache hosts can hold only a certain amount of cache operations in memory. It is possible, depending on system load, that some cache clients may not receive notifications before they are truncated in the cache host queues. Cache clients may also miss notifications when data is lost due to a cache server failure while the rest of the cluster remains running. In these cases, your cache client can discover that it has missed some cache notifications by using a failure notification. Your application can add a callback to receive failure notifications by using the AddFailureNotificationCallback method. For more information, see Add a Failure Notification Callback

EDIT : CacheItemRemovedCallback provides the key that is removed from the cache. Check if it's the always the same.I also recommand to not limit the distributed cached to a single item : if someone else add something in the cache your system will fails.

Cybermaxs
  • 24,378
  • 8
  • 83
  • 112
  • I removed the entire `` section but that doesn't seem to have changed anything. I still have multiple items. – Kalina Apr 29 '13 at 16:55
  • how do you know there is multiple items ? are you using PS cmdlet Get-Statistics ? – Cybermaxs Apr 29 '13 at 18:39
  • I was just assuming it was multiple cache items. I don't have access to PowerShell and can't check; but what else could the issue be? One cache item expiring multiple times? – Kalina May 01 '13 at 14:57
  • Powershell is a pre-requisite of AppFabric Caching, so you can run cmdlet Get-CacheStatistics bery easily using Admin Module (in Start Menu). Run this first to get the number of items. – Cybermaxs May 01 '13 at 15:09
  • I don't have admin access on the server and can't use PowerShell – Kalina May 01 '13 at 15:11
  • 1
    see edit and show a bit more code : maybe you re-add something in CacheItemRemovedCallback or you call multiple times RegisterCacheEntry – Cybermaxs May 01 '13 at 15:21
  • When it expires, I call RegisterCacheEntry to re-add the the same item with the same key to the same cache. – Kalina May 01 '13 at 15:38