Skip to content

Using the Caching API

thofrey edited this page Apr 1, 2014 · 5 revisions

Table of Contents

  1. Overview
  2. Accessing the Cache from a Mach-II Listener / Filter / Plugin / Endpoint
  3. Using the caching alias concept with the caching APIs

Overview

Mach-II comes bundled with an advanced and flexible enterprise ready caching sub-system. If you have not mastered the basics of the Mach-II caching package, be sure to read the Introduction to Caching before reading the advanced concepts and techniques below.

Accessing the Cache from a Mach-II Listener / Filter / Plugin / Endpoint

You can access cache strategies programatically from any Mach-II developer extended CFC. To do this, you should first create a reference to the cache in your Mach-II developer extended component configure() method, as follows:

    <cfset variables.myCache = getAppManager().getCacheManager().getCacheStrategyManager().getCacheStrategyByName("nameOfTheCacheYouWant") />

While this is not required, it's a useful convenience over having to type all of the above each and every time you want to reference a cache in your listener / filter / plugin / endpoint.

When you need to access the cache inside of a method in your listener / filter / plugin / endpoint, simply do the following:

    <cfset variables.myCache.put(uniqueKey, data) />

or

    <cfset variables.myCache.get(uniqueKey) />

Ensure that you pass a unique key when you or put() into the cache or you will overwrite an existing key with the same name in the given cache.

Here is another example that checks to see if caching is enabled:

    <cfif variables.myCache.isCacheEnabled() >
        <cfset data = variables.myCache.get(uniqueKey) />

        <cfif NOT isDefined("data") >
            <!--- Populate data however you would normally generate it here --->
            <cfset variables.myCache.put(uniqueKey, data) />
        </cfif>

    <cfelse>
        <!--- Populate data however you would normally generate it here --->
    </cfif>

Here is an example of how to clear all caches with a specific alias using a listener:

    <cffunction name="clearCacheByAlias" access="public" returntype="string" output="false">
        <cfargument name="event" type="MachII.framework.Event" required="true">

        <cfset var cacheAlias = event.getArg('alias')/>
        <cfset var module = event.getArg('module')/>
        <cfset var cacheManager = ""/>

        <!--- Get the right CacheManager context based on the module --->
        <cfif Len(module)>
            <cfset cacheManager = getAppManager().getModuleManager().getModule(module).getModuleAppManager().getCacheManager() />
        <cfelse>
            <cfset cacheManager = getAppManager().getCacheManager() />
        </cfif>

        <cfset cacheManager.clearCachesByAlias(cacheAlias,arguments.event, '')/>
    </cffunction>

If you are using modules then you need to call this listener from an event that is in the same context as the alias cache you want to clear. You can do this by putting my event in the base module, then call another event (also in the base module) that does nothing but pull the module name from the event args and announce the cache clear event in that module:

    <cfset announceEventInModule(module,"clear-alias-cache",event.getArgs())>

If you use IDs instead of aliases for your cache blocks you can just modify the function above to call this method in the cacheManager instead:

    <cfset cacheManager.clearCacheById(cacheId,arguments.event)/>

Using the caching alias concept with the caching APIs

One option for you to use if you are accessing the cache API directly is to use Java HashSet object to assign an alias to certain cache keys. Basically on each entry added to a specific cache, you would take that key and put an entry in the HashSet so you know all the associated keys. Each HashSet would contain a unique group of keys. For example:

If you are trying to cache different users notes you may have a cache key that contains the user-id, or the note-id. However because all notes can be altered by the admin at once there is a need to clear any note cache entry without disturbing other entries in the cache. You would create a HashSet "notepad-cache-group" and that HashSet would contain all keys that had been added dealing with notes.

Code Example Adding to cache with alias:

      getShortLifeCache().put(cacheKey, cacheValue);

      // if a cache group is passed in, add the key to that group
      if (cacheAlias neq "") {
            cachedHashSet = getShortLifeCache().get(cacheAlias);

            if (not isDefined("cachedHashSet")) {
                    cachedHashSet = CreateObject("java", "java.util.HashSet").init();
            }

            cachedHashSet.add(cacheKey);
            getShortLifeCache().put(cacheAlias, cachedHashSet);
      }

Code Example removing from cache by alias:

       cachedHashSet = getShortLifeCache().get(cacheAlias);
       if (isDefined("cachedHashSet")) {
            cachedKeySet = cachedHashSet.toArray();
            cachedHashSet.clear();

            for (intVar = 1; intVar lte ArrayLen(cachedKeySet); intVar = (intVar+1)) {
                    getShortLifeCache().remove(cachedKeySet[intVar]);
            }

            // remove the group key from the cache
            getShortLifeCache().remove(cacheAlias);
       }
Clone this wiki locally