Skip to content

Commit

Permalink
MDL-72837 core_cache: Add versioned cache support
Browse files Browse the repository at this point in the history
Adds new set_versioned and get_versioned APIs to cache, which means you can
request a specific version from cache and it will not return an outdated
version.

This is important when using multi-layer-caches where a local cache might have
an outdated version of the cache, but the shared cache has a current version.
With this feature, the content of the cache does not have to be rebuilt, as
it will automatically retrieve it from the shared cache if necessary.
  • Loading branch information
sammarshallou committed Feb 23, 2022
1 parent 9777852 commit 8a0f706
Show file tree
Hide file tree
Showing 10 changed files with 935 additions and 27 deletions.
79 changes: 78 additions & 1 deletion cache/classes/interfaces.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,34 @@ interface cache_loader {
*/
public function get($key, $strictness = IGNORE_MISSING);

/**
* Retrieves the value and actual version for the given key, with at least the required version.
*
* If there is no value for the key, or there is a value but it doesn't have the required
* version, then this function will return false (or throw an exception if you set strictness
* to MUST_EXIST).
*
* This function can be used to make it easier to support localisable caches (where the cache
* could be stored on a local server as well as a shared cache). Specifying the version means
* that it will automatically retrieve the correct version if available, either from the local
* server or [if that has an older version] from the shared server.
*
* If the cached version is newer than specified version, it will be returned regardless. For
* example, if you request version 4, but the locally cached version is 5, it will be returned.
* If you request version 6, and the locally cached version is 5, then the system will look in
* higher-level caches (if any); if there still isn't a version 6 or greater, it will return
* null.
*
* You must use this function if you use set_versioned.
*
* @param string|int $key The key for the data being requested.
* @param int $requiredversion Minimum required version of the data
* @param int $strictness One of IGNORE_MISSING or MUST_EXIST.
* @param mixed $actualversion If specified, will be set to the actual version number retrieved
* @return mixed Data from the cache, or false if the key did not exist or was too old
*/
public function get_versioned($key, int $requiredversion, int $strictness = IGNORE_MISSING, &$actualversion = null);

/**
* Retrieves an array of values for an array of keys.
*
Expand Down Expand Up @@ -82,6 +110,29 @@ public function get_many(array $keys, $strictness = IGNORE_MISSING);
*/
public function set($key, $data);

/**
* Sets the value for the given key with the given version.
*
* The cache does not store multiple versions - any existing version will be overwritten with
* this one. This function should only be used if there is a known 'current version' (e.g.
* stored in a database table). It only ensures that the cache does not return outdated data.
*
* This function can be used to help implement localisable caches (where the cache could be
* stored on a local server as well as a shared cache). The version will be recorded alongside
* the item and get_versioned will always return the correct version.
*
* The version number must be an integer that always increases. This could be based on the
* current time, or a stored value that increases by 1 each time it changes, etc.
*
* If you use this function you must use get_versioned to retrieve the data.
*
* @param string|int $key The key for the data being set.
* @param int $version Integer for the version of the data
* @param mixed $data The data to set against the key.
* @return bool True on success, false otherwise.
*/
public function set_versioned($key, int $version, $data): bool;

/**
* Sends several key => value pairs to the cache.
*
Expand Down Expand Up @@ -436,6 +487,32 @@ public function load_for_cache($key);
public function load_many_for_cache(array $keys);
}

/**
* Versionable cache data source.
*
* This interface extends the main cache data source interface to add an extra required method if
* the data source is to be used for a versioned cache.
*
* @package core_cache
*/
interface cache_data_source_versionable extends cache_data_source {
/**
* Loads the data for the key provided ready formatted for caching.
*
* If there is no data for that key, or if the data for the required key has an older version
* than the specified $requiredversion, then this returns null.
*
* If there is data then $actualversion should be set to the actual version number retrieved
* (may be the same as $requiredversion or newer).
*
* @param string|int $key The key to load.
* @param int $requiredversion Minimum required version
* @param mixed $actualversion Should be set to the actual version number retrieved
* @return mixed What ever data should be returned, or false if it can't be loaded.
*/
public function load_for_cache_versioned($key, int $requiredversion, &$actualversion);
}

/**
* Cacheable object.
*
Expand Down Expand Up @@ -521,4 +598,4 @@ public function check_state($key, $ownerid);
* Things such as unfortunate timeouts etc could cause this situation.
*/
public function __destruct();
}
}
Loading

0 comments on commit 8a0f706

Please sign in to comment.