CacheAdapter–V2 Now with memcached support

Previously I blogged about my CacheAdapter project that is available as a Nuget package and allows you to program against a single interface implementation, but have support for using Memory, ASP.NET Web or Windows AppFabric cache mechanisms via configuration.

I am happy to announce that my CacheAdapter now has support for memcached. Version 2 of the Nuget package is available here. Alternatively, all the source code is available here.

What this now means is you can write one line of code to get or store an item in the cache, and that code can automatically support using Windows AppFabric, memcached, MemoryCache or ASP.NET web cache. No code change required.

I am particularly happy about having memcached support as it means a few things:

  • Free / Open Source: It is a free, well established open source caching engine that is widely used in many applications.
  • Easy: It is easy to setup.
  • Simple and Cheap: It provides an alternative to using Windows AppFabric. AppFabric can be a little tricky to setup sometimes. If you are using Windows Azure, AppFabric is a simple checkbox BUT you need to pay extra for the privilege of using it based on how much you use the cache service. By contrast, memcached can be installed easily on Azure and requires no extra cost whatsoever.
  • Auto fail over support: In addition, Windows AppFabric has some limitations for a relatively small cache farm. AppFabric utilises a “lead host” to co-ordinate small cache farms of 3 or less cache servers. If the lead host goes down, they all go down. The memcached implementation has no reliance on any single point of failure so if one memcached node fails, requests will automatically be redirected to the nodes that are alive. If the dead node comes back alive again, it is re-introduced to the cache pool after about 1 minute or so. At worst, it results in a few cache misses.

Note: This release contains a few namespace changes that may break older versions if you are using the objects directly. Namely AppFabric object support has been moved from the Glav.CacheAdapter.Distributed namespace to the Glav.CacheAdapter.Distributed.AppFabric namespace. This is to allow differentiation from AppFabric and memcached within the distributed namespace.

In addition, at the request of some users, I have added a simple ‘Add’ method to the ICacheProvider interface for ease of use. The interface now looks like this:

public interface ICacheProvider
{
    T Get<T>(string cacheKey, DateTime absoluteExpiryDate, GetDataToCacheDelegate<T> getData, bool addToPerRequestCache = false) where T : class;
    T Get<T>(string cacheKey, TimeSpan slidingExpiryWindow, GetDataToCacheDelegate<T> getData, bool addToPerRequestCache = false) where T : class;
    void InvalidateCacheItem(string cacheKey);
    void Add(string cacheKey, DateTime absoluteExpiryDate, object dataToAdd);
    void Add(string cacheKey, TimeSpan slidingExpiryWindow, object dataToAdd);
    void AddToPerRequestCache(string cacheKey, object dataToAdd);
}

So that is it. I hope you enjoy using memcached support within the CacheAdapter.

17 Comments

  • Hi Glav, nicely done! Really like your caching framework :)

    A quick question: your framework doesn't provide for synchronizing cache access (i.e. multiple requests to read/write the same cache item simultaneously). Or is this something that is taken care of by the specific cache implementation used (currently I am using System.Runtime.Caching.MemoryCache)?

  • Hi manna,

    This is typically taken care of by the respective cache mechanism. AFAIK, each cache implementation takes care of this for you.

  • Hey Glav,

    How about adding a CacheSetting for None or Off. Just in case you want to turn it off for what ever reason in production. Or is this possible another way?

    public enum CacheSetting
    {
    Memory,
    Web,
    AppFabric,
    memcached,
    None
    }

    Cheers
    Dan.


  • Hey Dan,

    What I have generally done in the past is have cache settings for individual elements (say a cache expiry setting for customer list, one for customer type etc...) and set these specific settings to 0 if I dont want them c cached. Obviously this means work on your part to implement this. Having a cache setting of None would be relatively easy to do though. Can u provide an example use case of where or how you would see this being used though?

    Thanks for the feedback.

  • Hi Joe,

    Main reason for .Net 4 only is the MemoryCache implementation. The AppFabric assemblies are .net 3.5 SP1 so it should be ok. It would be easy enough to remove the memory cache implementations though. I'll have a look at the alternatives in terms of supporting other similar cache mechanisms but aimed at 3.5. It sounds like it might be better to fork the code and customise it slightly for your own needs but I'll have a look. The memcached and ASP.NET web cache have no .Net 4 requirements.

  • Hi Rasika,

    I'd be happy to try and resolve this issue. Could you please provide me a small bit of code that reproduces this issue? You can either log an issue via Bitbucket and provide an attachment here:
    https://bitbucket.org/glav/cacheadapter/issues?status=new&status=open

    or you can email me at glav @ aspalliance.com

  • Hi Rasika,

    Thanks for that. I have added the attachment to the issue log in Bitbucket and will look into the issue.

    Thanks for reporting it.

  • HI Rasika,
    Hopefully you got my email, however the problem you reported was because of incorrect port numbers. In the config file you had a port number of 22333 ( I think) which looks close to the default port number of AppFabric (which is 22233). However, if you simply run memcached with the default installation, it uses a default port 11211. Changing the port number in the config to 11211 should resolve the issue.

  • HI Rasika,

    Sent u an email but basically the code example u sent me worked fine for me after I changed the port number. Check the email for details.

  • You will support NCache and enterprise library caching application block?

  • Hi Roberto,

    I hadn't thought about it but I certainly could add support if people want that. The enterprise library caching application block is not something I would typically target as it is an abstraction in itself and I would rather not provide an abstraction over an abstraction, not to mention the dependencies that would entail. I dont have much experience with NCache but if people want it, I'd be happy to take a look.
    If it is something you really want, please log an issue/feature request over at
    https://bitbucket.org/glav/cacheadapter/issues?status=new&status=open

  • I love the idea of having CacheAdapter as a way of switching between HttpRuntime.Cache and AppFabric, but when I configure my web.config for AppFabric, I get an error (following). It works great for "Memory", but fails for "AppFabric". I used Nuget.

    I've Googled but nobody else seems to be having this problem....

    The type initializer for 'Glav.CacheAdapter.Core.DependencyInjection.AppServices' threw an exception. ---> Microsoft.ApplicationServer.Caching.DataCacheException: ErrorCode:SubStatus:Authorization token passed by user Invalid. ---> System.FormatException: The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.

  • Hi Bud,

    It simply looks like you have an incorrect character as the auth key for the AppFabric cache. If you can send your config through I can have a quick look. You can contact me via @glav on twitter or glav AT aspalliance.com

  • Hallo Glav,
    is this project still alive and kicking? :)
    I was looking right in those days to some abstraction over the base asp.net caching just in case I will switch to a multi server cloud environment (who knows what happens when you launch your SaaS software LOL).

    Another question (I haven't read your docs yet so forgive me), does AppFabric (guess yes) and MEMCached (guess not............) have all the invalidation features of the asp.net cache or the .net cache like cache priority (that can even be set to NEVER EXPIRE), fixed times and sliding times?

    Thanks in advance

  • Hi Manight,

    Yes its still alive even though I only sporadically do changes to it. I still have an outstanding PULL request to integrate.

    However, I do plan further development around for things like cache dependencies and Redis support.

    To answer your questions though, this abstraction layer currently only offers the lowest level of API that is common across all platforms so specific cache invalidation features are not in place and this one of the things I will be working on. That is, to provide cache invalidation across all platforms using the same API. So while directly asp.net cache and AppFabric do support advanced invalidation features, memcached does not, so the API only supports basic item invalidation at this point.

    Also, memcached does not support sliding cache expiry so defaults to explicit date time expiry.

    Feel free to lodge issues/tickets on the Bitbucket site where the code is hosted.

  • Thank you Glav for your responsiveness... I will definitely implement your soultion right now.
    Yes adding advance invalidation features (where supported would be great). For example now I can program it against .NET cache with all his sliding and priority invalidation features, so to squeeze at best my cache for more relevant objects, then if the thing grows and I have to switch to a distributed cache, those features won't be that important anymore because of added horsepower and could be simply ignored.
    A nice programming interface could be to request the expiration duration (or fixed time) as mandatory since this is common across al platforms and allow you to switch seamlessly from one to another, and then add at least the .NET/AppFabric (since this is a .NET cache layer project I think this makes sense) advanced invalidations that gets used only when the provider targets those systems.
    So for example you always add with key/object/time and in case of .NET/ASP.NET/AppFabric provider if you add Sliding Time OR Cache Priority, the TIME simply gest ignored, while if you use the other providers, the Sliding Time OR Cache Priority. This will let you program one time and get the best of all worlds.



    About the "provider" I mentioned, it could be nice to exploit the provider model also to have automatic injection and switch from one platform to another or maybe even use together.

  • Thanks Manight. Bear in mind the idea of this cache adapter is to allow seamless switching between cache implementations (such as ASP.Net, AppFabric or memcached) with no code change. Purely via configuration changes which works great. It also supports sliding expiry where possible (against ASP.Net caches) and calculates absolute expiry time against those caches where it does not support sliding windows.

    I see you have added some issues on the repository so will address those there.

    Thanks.

Comments have been disabled for this content.