Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

Cache API

From MoodleDocs

Cache API

This document details the Cache API aka MUC aka Moodle's Universal Cache. I've chosen to use a tutorial/example flow for this document always working with a theoretical module plugin called myplugin. There is also a Cache API - Quick reference if you would rather read that.

Basic usage

It's very easy to get started with the Cache API. It is designed to be as easy and as quick to use as possible and is predominantely self contained. All you need to do is add a definition for your cache and you are ready to start working with the Cache API.

Creating a definition

Cache definitions exist within the db/caches.php file for a component/plugin.
In the case of core that is the moodle/lib/db/caches.php file, in the case of a module that would be moodle/mod/myplugin/db/caches.php.

The definition is used API in order to understand a little about the cache and what it is being used for, it also allows the administrator to set things up especially for the definition if they want. From a development point of view the definition allows you to tell the API about your cache, what it requires, and any (if any) advanced features you want it to have.
The following shows a basic definition containing just the bare minimum: // moodle/mod/myplugin/db/caches.php $definitions = array(

   'mycache' => array(
       'mode' => cache_store::MODE_APPLICATION
   )

); This informs the API that the myplugin module has a cache called somedata and that it is an application (globally shared) cache.
When creating a definition thats the bare minimum, to provide an area (somedata) and declare the type of the cache application, session, or request.

An application cache is a shared cache, all users can access it.
Session caches are, well, just stores in the users session.
Request caches you can think of as static caches, only available to the user owning the request, and only alive until the end of the request.

There are of course many more options available that allow you to really take the cache by the reigns, you can read about some of the important ones further on, or skip ahead to #The definition section which details the available options in full.

Getting a cache object

Once your definition has been created you should bump the version number so that Moodle upgrades and processes the definitions file at which point your definition will be useable.

Now within code you can get a cache object to interact with in the following manner.

$cache = cache::make('mod_myplugin', 'mycache');

The cache::make method is a factory method, it will create a cache object to allow you to work with your cache. The cache object will be one of several classes chosen by the API based upon what your definition contains. All of these classes will extend the base cache class, and in nearly all cases you will get one of cache_application, cache_session, or cache_request depending upon the mode you selected.

Using your cache object

Once you have a cache object (will extend the cache class and implements cache_loader) you are ready to start interacting with the cache.

Of course there are three basic basic operations. get, set, and delete.

The first is to send something to the cache. $result = $cache->set('key', 'value'); Easy enough. The key must an int or a string. The value can be absolutely anything your want. The result is true if the operation was a success, false otherwise.

The second is to fetch something from the cache. $data = $cache->get('key'); $data will either be what ever was being stored in the cache, or false if the cache could not find the key.

The third and final operation is delete. $result = $cache->delete('key'); Again just like set the result will either be true if the operation was a success, or false otherwise.

You can also set, get, and delete multiple key=>value pairs in a single transaction. $result = $cache->set_many(array(

   'key1' => 'data1',
   'key3' => 'data3'

)); // $result will be the number of pairs sucessfully set.

$result = $cache->get_many(array('key1', 'key2', 'key3')); print_r($result); // Will print the following: // array( // 'key1' => 'data1', // 'key2' => false, // 'key3' => 'data3' // )

$result = $cache->delete_many(array('key1', 'key3'); // $result will be the number of records sucessfully deleted.

That covers the basic operation of the Cache API.
In many situations there is not going to be any more to it than that.

Ad-hoc Caches

This is the alternative method of using the cache API.
It involves creating a cache using just the required params at the time that it is required. It doesn't require that a definition exists making it quicker and easier to use, however it can only use the default settings and is only recommended for insignificant caches (rarely used during operation, never to be mapped or customised, only existsing in a single place in code).

Once a cache object has been retrieved it operates exactly as the same as a cache that has been created for a definition.

To create an ad-hoc cache you would use the following: $cache = cache::make_with_params(cache_store::MODE_APPLICATION, 'mod_myplugin', 'mycache');

Really don't be lazy, if you don't have a good reason to use an ad-hoc cache you should be spending a extra 5 minutes creating a definition.

The definition

The above section illustrated how to create a basic definition, specifying just the area name (the key) and the mode for the definition. Those being the two required properties for a definition.
There are as well many other options that will let you make the most of the Cache API and will undoubtedly be required when implementing and converting cache solutions to the Cache API.

The following details the options available to a definition and there defaults if not applied:

$definitions = array(

   // The name of the cache area is the key. The component/plugin will be picked up from the file location.
   'area' => array(
       'mode' => cache_store::MODE_*,
       'requireidentifiers' => array('ident1', 'ident2'),
       'requiredataguarantee' => false,
       'requiremultipleidentifiers' => false,
       'requirelockingread' => false,
       'requirelockingwrite' => false,
       'maxsize' => null,
       'overrideclass' => null,
       'overrideclassfile' => null,
       'datasource' => null,
       'datasourcefile' => null,
       'persistent' => false,
       'persistentmaxsize' => null,
       'ttl' => 0,
       'mappingsonly' => false,
       'invalidationevents' => array('event1', 'event2'),
   )

);

requireidentifiers
[array] An array of identifiers that must be provided to the cache when it is created.
requiredataguarantee
[bool] If set to true then only stores that can guarantee data will remain available once set will be used.
requiremultipleidentifiers
[bool] If set to true then only stores that support multiple identifiers will be used.
requirelockingread
[bool] If set to true then a lock will be gained before reading from the cache store. It is recommended not to use this setting unless 100% absolutely positively required.
Remember 99.9% of caches will NOT need this setting.
This setting will only be used for application caches presently.
requirelockingwrite
[bool] If set to true then a lock will be gained before writing to the cache store. As above this is not recommended unless truly needed. Please think about the order of your code and deal with race conditions there first.
This setting will only be used for application caches presently.
maxsize
[int] If set this will be used as the maximum number of entries within the cache store for this definition.
Its important to note that cache stores don't actually have to acknowledge this setting or maintain it as a hard limit.
overrideclass
[string] A class to use as the loader for this cache. This is an advanced setting and will allow the developer of the definition to take 100% control of the caching solution.
Any class used here must inherit the cache_loader interface and must extend default cache loader for the mode they are using.
overrideclassfile
[string] Suplements the above setting indicated the file containing the class to be used. This file is included when required.
datasource
[string] A class to use as the data loader for this definition.
Any class used here must inherit the cache_data_loader interface.
datasourcefile
[string] Suplements the above setting indicated the file containing the class to be used. This file is included when required.
persistent
[bool] This setting does two important things. First it tells the cache API to only instantiate the cache structure for this definition once, further requests will be given the original instance.
Second the cache loader will keep an array of the items set and retrieved to the cache during the request.
This has several advantages including better performance without needing to start passing the cache instance between function calls, the downside is that the cache instance + the items used stay within memory.
Consider using this setting when you know that there are going to be many calls to the cache for the same information or when you are converting existing code to the cache and need to access the cache within functions but don't want to add it as an argument to the function.
persistentmaxsize
[int] This supplements the above setting by limiting the number of items in the caches persistent array of items.
Tweaking this setting lower will allow you to minimise the memory implications above while hopefully still managing to offset calls to the cache store.
ttl
[int] A time to live for the data (in seconds). It is strongly recommended that you don't make use of this and instead try to create an event driven invalidation system.
Not all cache stores will support this natively and there are undesired performance impacts if the cache store does not.
mappingsonly
[bool] If set to true only the mapped cache store(s) will be used and the default mode store will not. This is a super advanced setting and should not be used unless absolutely required. It allows you to avoid the default stores for one reason or another.
invalidationevents
[array] An array of events that should cause this cache to invalidate some or all of the items within it.

The loader

Using a data source

Developing cache plugins