There are times in code when you will want to disable the cache stores.
While the cache API must still be functional in order for calls to it to work it is possible to disable the use of the cache stores separately so that you can be sure only the cache will function in all circumstances.
// Disable the cache store at the start of your script with:
define('CACHE_DISABLE_STORES', true);
// Disable the cache within your script when you want with:
cache_factory::disable_stores();
// If you disabled it using the above means you can re-enable it with:
Like above there are times when you want the cache to avoid initialising anything it doesn't absolutely need. Things such as installation and upgrade require this functionality.
When the cache API is disabled it is still functional however special "disabled" classes will be used instead of the regular classes that make the Cache API tick.
These disabled classes do the least work possible and through this means we avoid all manner of intialisation and configuration.
* There are two ways to get a loader, the first with a definition (discussed below) the second with params. When params are used they are turned into an adhoc definition with default params.
* A loader is passed three things when being constructed, a definition, a store, and another loader or datasource if there is either.
* If a data source is provided then requests for an item that is not cached will be passed to the data source and that will be expected to load the data. If it loads data, that data is stored in each store on its way back to the user.
* There are three core loaders. One for each application, session and request.
* A custom loader can be used. It will be provided by the definition (thus cannot be used with ad hoc definitions) and must override the appropriate core loader
* The loader handles ttl (time to live) for stores that don't natively support ttl.
* The application loader handles locking for stores that don't natively support locking.
### Store
The store is the bridge between the cache API and a cache solution.
Cache store plugins exist within moodle/cache/store.
The administrator of a site can configure multiple instances of each plugin, the configuration gets initialised as a store for the loader when required in code (during construction of the loader).
The following points highlight things you should know about stores.
* A cache_store interface is used to define the requirements of a store plugin.
* The store plugin can inherit the cache_is_lockable interface to handle its own locking.
* The store plugin can inherit the cache_is_key_aware interface to handle is own has checks.
* Store plugins inform the cache API about the things they support. Features can be required by a definition.
* Data guarantee - Data is guaranteed to exist in the cache once it is set there. It is never cleaned up to free space or because it has not been recently used.
* Multiple identifiers - Rather than a single string key, the parts that make up the key are passed as an array.
* Native TTL support - When required, the store supports native ttl and doesn't require the cache API to manage ttl of things given to the store.
_Definitions were not a part of the previous proposal._
Definitions are cache definitions. They will be located within a new file for each component/plugin at **db/caches.php**.
They can be used to set all of the requirements of a cache instance and are used to ensure that a cache can only be interacted with in the same way no matter where it is being used.
It also ensures that caches are easy to use, the config is stored in the definition and the developer using the cache does not need to know anything about its inner workings.
* simplekeys - Set to true if items will always and only have simple keys. Simple keys may contain a-zA-Z0-9_. If set to true we use the keys as they are without hashing them. Good for performance and possible because we know the keys are safe.
* simpledata - Set to true if you know that you will only be storing scalar values or arrays of scalar values. Avoids costly investigation of data types.
* requiresearchable - If set to true only stores that support key searching will be used for this definition. Its not recommended to use this unless absolutely unavoidable.
* maxsize - This gives a cache an indication about the maximum items it should store. Cache stores don't have to use this, it is up to them to decide if its required.
* overrideclass - If provided this class will be used for the loader. It must extend one of the core loader classes (based upon mode).
It's important to note that internally the definition is also aware of the component. This is picked up when the definition is read, based upon the location of the caches.php file.
As noted the persistent option causes the loader generated for this definition to be stored when first created. Subsequent requests for this definition will be given the original loader instance.
This controls the options available to the user when configuring the sharing of a definitions cached data.
By default all sharing options are available to select. This particular option allows the developer to limit the options available to the admin configuring the cache.
Data sources allow cache _misses_ (requests for a key that doesn't exist) to be handled and loaded internally.
The loader gets used as the last resort if provided and means that code using the cache doesn't need to handle the situation that information isn't cached.
They can be specified in a cache definition and must implement the cache_data_source interface.
There is a helper class called cache_helper which is abstract with static methods.
This class handles much of the internal generation and initialisation requirements.
In normal use this class will not be needed outside of the API (mostly internal use only)
### Configuration
There are two configuration classes cache_config and cache_config_writer.
The reader class is used for every request, the writer is only used when modifying the configuration.
Because the cache API is designed to cache database configuration and meta data it must be able to operate prior to database configuration being loaded.
To get around this we store the configuration information in a file in the dataroot.
The configuration file contains information on the configured store instances, definitions collected from definition files, and mappings.
That information is stored and loaded in the same way we work with the lang string files.
This means that we use the cache API as soon as it has been included.
### Invalidation
Cache information can be invalidated in two ways.
1. pass a definition name and the keys to be invalidated (or none to invalidate the whole cache).
The second method is a lot more intensive for the system. There are defined invalidation events that definitions can "subscribe" to (through the definitions invalidationevents option).
When you invalidate by event the cache API finds all of the definitions that subscribe to the event, it then loads the stores for each of those definitions and purges the keys from each store.