1. Home
  2. >
  3. Development
  4. >
  5. Adding CacheBox to your CFML application

Adding CacheBox to your CFML application

CacheBox is a tool that adds caching to your application to speed things up. It is not dependent on a single cache which makes it very powerful when your application needs frequent change.

Creating cachebox

A Cache is like short-term memory. It is typically faster than the original data source. Accessing data from RAM is always faster than accessing it from the hard drive. Caching means saving frequently accessed data in-memory (short -term memory).

Getting started

CacheBox is a great box product that is easy to implement and use. In this blog, we will focus on how to integrate a Default provider in a Preside Application. Preside is based on the ColdBox Framework, making it a good example of how to integrate a CacheBox basic provider.

Why use Cache?

Cache is a tool all modern applications need. As developers, we want the best page speed for our applications. One way to obtain that is by implementing cache. You always want to show the most current information, therefore it is important to be careful when using cache. Let’s take a library website as an example, books come and go and inventory changes rapidly, book stocks go up and down and new content is added regularly. Applying cache in this situation needs to be planned carefully, you gain speed but lose clients if stock and inventory is not up to date.

There are a few things we should take into account when we work with cache

  1. The lifetime for the cache
    1. It is recommended to not have a very high timeout to autoflush the cache. If we save a big query in the cache, refreshing the query after 5 or 10 minutes is no problem. By doing so, we have freshly cached information is as close as possible to the real database.
  2. Cache flushing after persistent actions
    1. We should have control when we cache an object, if there is any persistent action with that object it should remove the specific or generic cache. For instance. If we save book stock in cache and someone adds, edit, or removes any book from the database, the specific or generic cache should be removed to refresh.
  3. Clear cache on demand
    1. It is always handy to present an option to the user superadmin to flush the cache on demand. This way the user can renew the cache dataset when needed.

Integrations

To integrate a CacheBox provider there is a few steps to follow:

  1. Declare CacheBox provider
  2. Inject the CacheBox provider or use it.
  3. Use the mainly cacheProvider functions.
    1. get
    2. set
    3. delete
    4. flush
  4. Integrated advanced provider. Couchbase.

Declare CacheBox provider

Add the next settings in your application/config/Cachebox.cfc
In this example we are using the default ColdBox cache provider. Feel free to use another provider or even build your own if it is need.

component extends="preside.system.config.Cachebox" {
 
  function configure() {
    super.configure( argumentCollection=arguments );
 
    cachebox.caches.mycache = {
        provider   = "preside.system.coldboxModifications.cachebox.CacheProvider"
        , properties = {
            objectDefaultTimeout           = 300
          , objectDefaultLastAccessTimeout = 30
          , useLastAccessTimeouts          = true
          , reapFrequency                  = 20
          , freeMemoryPercentageThreshold  = 0
          , evictionPolicy                 = "LFU"
          , evictCount                     = 500
          , maxObjects                     = 2000
          , objectStore                    = "ConcurrentStore"
        }
    }
}

Inject the CacheBox provider or use it There are 2 ways to use the recently added CacheBox provider.

  1. Using dependency injection
    property name="myCache"                      inject="cachebox:mycache";
  2. Getting the caches from the controller superclass
    1. Regular ColdBox applications
      var caches = application.controller.getCachebox().getCaches()
    2. Preside applications
      var caches = getController().getCachebox().getCaches()
  3. The function above will return you a Struct with all the providers available (caches var). If you want to use a specific provider you can use it as followed.
    var myCache = caches['mycache']

Use the main cacheProvider functions

Once you have your Cache provider setting. You can use the next functions

  • Data to handler with the cache
    var _data = queryNew(
      "id,name"
      , "Integer,Varchar"
      , [
        {id=1,name="One"},
        {id=2,name="Two"},
        {id=3,name="Three"}
        ]
    );
  • Set data to Cache provider
    myCache .set(
      objectKey         = "testid"
      , object            = _data
    );
  • Get data from Cache provider
    var resultFromCache  = myCache .get( "testid");
  • GetorSet data from Cache provider
    myCache.getOrSet( "testid", function(){
      return queryNew(
        "id,name"
        , "Integer,Varchar"
        , [
          {id=1,name="One"},
          {id=2,name="Two"},
          {id=3,name="Three"}
          ]
      );
    } )
    
  • Clear object key from Cache provider
    myCache.clear( "testid");
  • Clear all Cache provider
    myCache.clearAll();

Integration of advanced providers. Couchbase

Couchbase Server is an open source, distributed, JSON document database.
It exposes a store with managed cache for high speed data operations, indexers for efficient queries and a powerful query engine for executing SQL-like queries. Couchbase

CacheBox Couchbase Provider Module

To install just drop into your modules folder or use CommandBox to install

box install preside-ext-toomba-couchbase

The Couchbase Provider for Cachebox is a ColdBox 4.x module that allows you to connect CacheBox to a Couchbase cluster and leverage that cluster in your ColdBox applications. This extension is based on Couchbase CacheBox Provider Module for Coldbox

To complete this integration we supposed you have a couchbase server running. Here is an example to use this server locally with docker couchbase:

couchbase:
    image: couchbase/server
    volumes:
      - ./couchbase:/opt/couchbase/var
    ports:
      - 8091-8094:8091-8094
      - 11210-11211:11210-11211

Configure the Couchbase settings. Add the next setting in your Cachebox.cfc

component extends="preside.system.config.Cachebox" {
 
  function configure() {
    super.configure( argumentCollection=arguments );
 
    cachebox.caches.couchbase = {
        provider   = "app.extensions.preside-ext-toomba-couchbase.modules.couchbase-provider.models.CouchbaseColdboxProvider"
      , properties = {
          objectDefaultLastAccessTimeout = 30
        , useLastAccessTimeouts          = true
        , reapFrequency                  = 2
        , freeMemoryPercentageThreshold  = 0
        , evictionPolicy                 = "LFU"
        , evictCount                     = 200
        , maxObjects                     = 1000
        , objectStore                    = "ConcurrentStore"
        , objectDefaultTimeout          = 120
        , ignoreCouchbaseTimeouts       = true
        , bucketName                    = server.system.environment["PRESIDE_COUCHBASE_BUCKETNAME"] ?: "default"
        , servers                       = server.system.environment["PRESIDE_COUCHBASE_SERVERS"] ?: "localhost:8091"
        , user                          = server.system.environment["PRESIDE_COUCHBASE_USER"] ?: ""
        , password                      = server.system.environment["PRESIDE_COUCHBASE_PASSWORD"] ?: ""
 
      }
    }
  }
}

Querying data stored in Couchbase (Advanced uses)

N1QL (pronounced “nickel”) is Couchbase’s query language. The goal of N1QL is to give developers and enterprises an expressive, powerful, and complete language for querying, transforming, and manipulating JSON data. Hence, N1QL supports a full set of SELECT, INSERT, UPDATE, DELETE, MERGE statements along with a rich set of expressions and operators. N1QL is inspired from SQL.

There is not a “query” method available by default in the Couchbase Provider, but is possible to use that functionality using the Couchbase Client, that is accesible by the Provider, so just adding a function like this to the provider:

any function query(required any query) output="false" {
    return getCouchbaseClient().n1qlQuery(statement = arguments.query);
}

By using that function we can run N1QL queries on our Couchbase server.

var query = "SELECT * FROM BUCKETNAME";
var data = couchbaseCache.query(query);

References

 

 

You might find these articles interesting too