multiple configuration not working

Issue #38 closed
Former user created an issue

i am using Glav cache adapter 4.0 for data caching on web farm. For better performance, i am storing cached data in memory on individual server and store the cache key along with time stamp for invalidation on Redis. while fetching data from memory cache, i need to verify on Redis if the cache key is still valid. for this i need to have 2 config setting for glav adapter, one for memory cache on web server and other for central Redis data store. Here problem i am facing looks like Glav adapter is is not able to switch between different config settings.

below is sample methods using both the config but it looks that the both the cache provider instances have same configurations :

    internal void InvalidateCacheIfOldTimaStamp(string key)
    {
        if (GateConfig.Central_IsCacheEnabled == false)
            return;
        Dictionary<string, DateTime> data = new Dictionary<string, DateTime>();
        data = cacheProvider.Get<Dictionary<string, DateTime>>("C_" + key, new TimeSpan(0, 1440, 0), () =>
        {
            data.Add(key, DateTime.Now);
            return data;
        });

        Dictionary<string, DateTime> data1 = new Dictionary<string, DateTime>();
        data1 = centralCacheProvider.Get<Dictionary<string, DateTime>>("M_" + key, new TimeSpan(0, 1440, 0), () =>
        {
            data1.Add(key, DateTime.Now.AddDays(-1));
            return data;
        });

        if (data[key] < data1[key])
        {
            cacheProvider.InvalidateCacheItem(key);  
        }
    }

    protected internal ICacheProvider cacheProvider
    {
        get
        {
            var cp = AppServices.Cache;
            cp.CacheConfiguration.CacheToUse = Config.CachingType;
            cp.CacheConfiguration.IsCacheEnabled = Config.IsCacheEnabled;
            cp.CacheConfiguration.IsCacheDependencyManagementEnabled = Config.Cache_IsCacheDependencyManagementEnabled;
            cp.CacheConfiguration.DependencyManagerToUse = Config.Cache_DependencyManagerToUse;
            cp.CacheConfiguration.DistributedCacheServers = Config.Cache_DistributedCacheServers;
            cp.CacheConfiguration.CacheSpecificData = Config.Cache_CacheSpecificData;
            return cp;
        }
    }

    protected internal ICacheProvider centralCacheProvider
    {
        get
        {
            var cp = AppServices.Cache;
            cp.CacheConfiguration.CacheToUse = Config.Central_CacheToUse;
            cp.CacheConfiguration.IsCacheEnabled = Config.Central_IsCacheEnabled;
            cp.CacheConfiguration.IsCacheDependencyManagementEnabled = Config.Central_IsCacheDependencyManagementEnabled;
            cp.CacheConfiguration.DependencyManagerToUse = Config.Central_DependencyManagerToUse;
            cp.CacheConfiguration.DistributedCacheServers = Config.Central_DistributedCacheServers;
            cp.CacheConfiguration.CacheSpecificData = Config.Central_CacheSpecificData;
            return cp;
        }
    }

Comments (2)

  1. Paul Glavich repo owner

    Hi, The CacheAdapter was not really designed in that way. The AppServices.Cache is a singleton type instance that is resolved from configuration. The only real way to switch providers using the current singleton binding mechanism provided is by specifying a new configuration to parse and resolve via AppServices.SetConfig(...). So switching config via this means is possible but would not be what you are after as it changes the single instance of the cache that AppServices.Cache points to. There are a few other ways to go about this. You can not use AppServices class as it is meant as a convenience class to enable easy access to the cache in your code but it does (as mentioned) only support a single instance/singleton scenario (ie. you can switch config, but there is no support for multiple config). Using your preferred inversion of control container/dependency injection engine, you could write up named instances to the ICache and ICacheProvider to provide the instances you want. Note that I haven't tried this in a multiple cache situation. My advice would be to implement your own ICache and extend the CacheAdapter code base to create a custom ICache implementation that, when asked to Add or GEt from cache, checks memory first, then redis. I have been thinking about how to best address this issue but it does require some thinking and design up front in order to try and get the most flexible setup and address the 80% use case.

  2. Paul Glavich repo owner
    • changed status to closed
    • edited description

    With the latest changes allowing fluent configuration, this should now be possible.

    So you can now do:

    var provider = CacheConfig.Create()
                    .UseMemcachedCache()
                    .UsingDistributedServerNode("127.0.0.1")
                    .BuildCacheProviderWithTraceLogging();
    

    And specify any of the supported cache engines to get different instances of your cache.

  3. Log in to comment