From eb6637682ec835d9ec50612b59637e8b9ff5f6f6 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Mon, 21 Oct 2013 14:04:07 +0200 Subject: [PATCH 1/4] Inject memoryCache into Autoloader. Remove recursion-prevention hack. --- lib/autoloader.php | 57 +++++++++++++++++++++++----------------------- lib/base.php | 6 ++++- 2 files changed, 34 insertions(+), 29 deletions(-) diff --git a/lib/autoloader.php b/lib/autoloader.php index b5b5891837..b0dc890409 100644 --- a/lib/autoloader.php +++ b/lib/autoloader.php @@ -15,6 +15,12 @@ class Autoloader { private $classPaths = array(); + /** + * Optional low-latency memory cache for class to path mapping. + * @var \OC\Memcache\Cache + */ + protected $memoryCache; + /** * Add a custom prefix to the autoloader * @@ -112,44 +118,39 @@ class Autoloader { * @param string $class * @return bool */ - protected $memoryCache = null; - protected $constructingMemoryCache = true; // hack to prevent recursion public function load($class) { - // Does this PHP have an in-memory cache? We cache the paths there - if ($this->constructingMemoryCache && !$this->memoryCache) { - $this->constructingMemoryCache = false; - try { - $this->memoryCache = \OC\Memcache\Factory::createLowLatency('Autoloader'); - } catch(\Exception $ex) { - // no caching then - fine with me - } - } + $pathsToRequire = null; if ($this->memoryCache) { $pathsToRequire = $this->memoryCache->get($class); - if (is_array($pathsToRequire)) { - foreach ($pathsToRequire as $path) { - require_once $path; - } - return false; - } } - // Use the normal class loading path - $paths = $this->findClass($class); - if (is_array($paths)) { + if (!is_array($pathsToRequire)) { + // No cache or cache miss $pathsToRequire = array(); - foreach ($paths as $path) { - if ($fullPath = stream_resolve_include_path($path)) { - require_once $fullPath; + foreach ($this->findClass($class) as $path) { + $fullPath = stream_resolve_include_path($path); + if ($fullPath) { $pathsToRequire[] = $fullPath; } } - - // Save in our memory cache - if ($this->memoryCache) { - $this->memoryCache->set($class, $pathsToRequire, 60); // cache 60 sec - } } + + if ($this->memoryCache) { + $this->memoryCache->set($class, $pathsToRequire, 60); // cache 60 sec + } + + foreach ($pathsToRequire as $fullPath) { + require_once $fullPath; + } + return false; } + + /** + * @brief Sets the optional low-latency cache for class to path mapping. + * @param \OC\Memcache\Cache $memoryCache Instance of memory cache. + */ + public function setMemoryCache(\OC\Memcache\Cache $memoryCache) { + $this->memoryCache = $memoryCache; + } } diff --git a/lib/base.php b/lib/base.php index ef574b2d89..53ea28b46b 100644 --- a/lib/base.php +++ b/lib/base.php @@ -371,6 +371,11 @@ class OC { // register autoloader require_once __DIR__ . '/autoloader.php'; self::$loader = new \OC\Autoloader(); + spl_autoload_register(array(self::$loader, 'load')); + try { + self::$loader->setMemoryCache(\OC\Memcache\Factory::createLowLatency('Autoloader')); + } catch(\Exception $ex) { + } self::$loader->registerPrefix('Doctrine\\Common', 'doctrine/common/lib'); self::$loader->registerPrefix('Doctrine\\DBAL', 'doctrine/dbal/lib'); self::$loader->registerPrefix('Symfony\\Component\\Routing', 'symfony/routing'); @@ -378,7 +383,6 @@ class OC { self::$loader->registerPrefix('Sabre\\VObject', '3rdparty'); self::$loader->registerPrefix('Sabre_', '3rdparty'); self::$loader->registerPrefix('Patchwork', '3rdparty'); - spl_autoload_register(array(self::$loader, 'load')); // set some stuff //ob_start(); From f5e2b92688b269f83e401f8e92758e60d92384d2 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Mon, 21 Oct 2013 15:21:37 +0200 Subject: [PATCH 2/4] Only use autoloader cache when 'instanceid' is available. --- lib/base.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/base.php b/lib/base.php index 53ea28b46b..83417c52a5 100644 --- a/lib/base.php +++ b/lib/base.php @@ -371,11 +371,6 @@ class OC { // register autoloader require_once __DIR__ . '/autoloader.php'; self::$loader = new \OC\Autoloader(); - spl_autoload_register(array(self::$loader, 'load')); - try { - self::$loader->setMemoryCache(\OC\Memcache\Factory::createLowLatency('Autoloader')); - } catch(\Exception $ex) { - } self::$loader->registerPrefix('Doctrine\\Common', 'doctrine/common/lib'); self::$loader->registerPrefix('Doctrine\\DBAL', 'doctrine/dbal/lib'); self::$loader->registerPrefix('Symfony\\Component\\Routing', 'symfony/routing'); @@ -383,6 +378,7 @@ class OC { self::$loader->registerPrefix('Sabre\\VObject', '3rdparty'); self::$loader->registerPrefix('Sabre_', '3rdparty'); self::$loader->registerPrefix('Patchwork', '3rdparty'); + spl_autoload_register(array(self::$loader, 'load')); // set some stuff //ob_start(); @@ -438,6 +434,14 @@ class OC { } self::initPaths(); + if (OC_Config::getValue('instanceid', false)) { + // \OC\Memcache\Cache has a hidden dependency on + // OC_Util::getInstanceId() for namespacing. See #5409. + try { + self::$loader->setMemoryCache(\OC\Memcache\Factory::createLowLatency('Autoloader')); + } catch(\Exception $ex) { + } + } OC_Util::isSetLocaleWorking(); // set debug mode if an xdebug session is active From dde832b76cf9dc17be03491e7130790269843d43 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Mon, 21 Oct 2013 15:35:52 +0200 Subject: [PATCH 3/4] Only write-back on cache miss. --- lib/autoloader.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/autoloader.php b/lib/autoloader.php index b0dc890409..3228ca29b2 100644 --- a/lib/autoloader.php +++ b/lib/autoloader.php @@ -133,10 +133,10 @@ class Autoloader { $pathsToRequire[] = $fullPath; } } - } - if ($this->memoryCache) { - $this->memoryCache->set($class, $pathsToRequire, 60); // cache 60 sec + if ($this->memoryCache) { + $this->memoryCache->set($class, $pathsToRequire, 60); // cache 60 sec + } } foreach ($pathsToRequire as $fullPath) { From c85cc13d1ab926e6b75728ff45b84f4a53a724af Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Tue, 22 Oct 2013 11:16:08 +0200 Subject: [PATCH 4/4] Allow null as cache parameter (if no cache was found) and for cache removal. --- lib/autoloader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/autoloader.php b/lib/autoloader.php index 3228ca29b2..3451f799e1 100644 --- a/lib/autoloader.php +++ b/lib/autoloader.php @@ -150,7 +150,7 @@ class Autoloader { * @brief Sets the optional low-latency cache for class to path mapping. * @param \OC\Memcache\Cache $memoryCache Instance of memory cache. */ - public function setMemoryCache(\OC\Memcache\Cache $memoryCache) { + public function setMemoryCache(\OC\Memcache\Cache $memoryCache = null) { $this->memoryCache = $memoryCache; } }