From 9b9e88f7f692d7daf6c19deb2428431b15069604 Mon Sep 17 00:00:00 2001 From: Jan-Hendrik Willms <tleilax+studip@gmail.com> Date: Thu, 22 Jun 2023 11:33:08 +0000 Subject: [PATCH] wrap any cache other than memory cache into a wrapper that caches the cache in memory, fixes #2202 Closes #2202 Merge request studip/studip!1782 --- lib/classes/StudipCacheFactory.class.php | 26 +++++---- lib/classes/StudipCacheWrapper.php | 67 ++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 11 deletions(-) create mode 100644 lib/classes/StudipCacheWrapper.php diff --git a/lib/classes/StudipCacheFactory.class.php b/lib/classes/StudipCacheFactory.class.php index 5332e067881..77c5973ac1a 100644 --- a/lib/classes/StudipCacheFactory.class.php +++ b/lib/classes/StudipCacheFactory.class.php @@ -54,11 +54,9 @@ class StudipCacheFactory /** - * @param Config an instance of class Config which will be used to - * determine the class of the implementation of interface - * StudipCache - * - * @return void + * @param Config $config an instance of class Config which will be used to + * determine the class of the implementation of interface + * StudipCache */ public static function setConfig($config) { @@ -68,8 +66,6 @@ class StudipCacheFactory /** * Resets the configuration and voids the cache instance. - * - * @return void */ public static function unconfigure() { @@ -174,18 +170,26 @@ class StudipCacheFactory } /** - * Return an instance of a given class using some arguments + * Return an instance of a given class using some arguments. Unless the + * memory cache is instantiated, the cache will be wrapped in a wrapper + * class that uses a memory cache to reduce accesses to the cache. * - * @param string the name of the class - * @param array an array of arguments to be used by the constructor + * @param string $class the name of the class + * @param array $arguments an array of arguments to be used by the constructor * * @return StudipCache an instance of the specified class */ public static function instantiateCache($class, $arguments) { $reflection_class = new ReflectionClass($class); - return (is_array($arguments['config']) && count($arguments['config']) > 0) + $cache = (is_array($arguments['config']) && count($arguments['config']) > 0) ? $reflection_class->newInstanceArgs($arguments['config']) : $reflection_class->newInstance(); + + if ($class !== StudipMemoryCache::class) { + return new StudipCacheWrapper($cache); + } + + return $cache; } } diff --git a/lib/classes/StudipCacheWrapper.php b/lib/classes/StudipCacheWrapper.php new file mode 100644 index 00000000000..65c5edb2232 --- /dev/null +++ b/lib/classes/StudipCacheWrapper.php @@ -0,0 +1,67 @@ +<?php + +/** + * The cache wrapper wraps a memory cache around another cache. This should + * reduce the accesses to the actual cache. + * + * @author Jan-Hendrik Willms <tleilax+studip@gmail.com> + * @license GPL2 or any later version + * @since Stud.IP 5.4 + */ +class StudipCacheWrapper implements StudipCache +{ + const DEFAULT_MEMORY_EXPIRATION = 60; + + protected $actual_cache; + protected $memory_cache; + + public function __construct(StudipCache $actual_cache) + { + $this->actual_cache = $actual_cache; + $this->memory_cache = new StudipMemoryCache(); + } + + /** + * @inheritdoc + */ + public function expire($arg) + { + $this->memory_cache->expire($arg); + $this->actual_cache->expire($arg); + } + + /** + * @inheritdoc + */ + public function flush() + { + $this->memory_cache->flush(); + $this->actual_cache->flush(); + } + + /** + * @inheritdoc + */ + public function read($arg) + { + $cached = $this->memory_cache->read($arg); + if ($cached !== false) { + return $cached; + } + + $cached = $this->actual_cache->read($arg); + if ($cached !== false) { + $this->memory_cache->write($arg, $cached, self::DEFAULT_MEMORY_EXPIRATION); + } + return $cached; + } + + /** + * @inheritdoc + */ + public function write($name, $content, $expires = self::DEFAULT_EXPIRATION) + { + $this->memory_cache->expire($name); + $this->actual_cache->write($name, $content, $expires); + } +} -- GitLab