diff options
author | Julius Härtl <jus@bitgrid.net> | 2022-12-08 10:35:57 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-08 10:35:57 +0100 |
commit | fa7364ed179227451cf5ac305aa76a6e09a2e75b (patch) | |
tree | f5782ca9046920e5ed6ee3cca07cdd90e38c35c2 | |
parent | f1cc6cdf01dd2ef21292a078828481fb744fa393 (diff) | |
parent | 4bcaeb6c2cd0e9c5bb87995aac8df849bedd0b70 (diff) | |
download | nextcloud-server-fa7364ed179227451cf5ac305aa76a6e09a2e75b.tar.gz nextcloud-server-fa7364ed179227451cf5ac305aa76a6e09a2e75b.zip |
Merge pull request #35223 from nextcloud/perf/container-autoload
Smaller performance optimizations
-rw-r--r-- | lib/base.php | 1 | ||||
-rw-r--r-- | lib/private/AppFramework/DependencyInjection/DIContainer.php | 19 | ||||
-rw-r--r-- | lib/private/L10N/Factory.php | 13 | ||||
-rw-r--r-- | lib/private/Server.php | 1 | ||||
-rw-r--r-- | lib/private/ServerContainer.php | 11 | ||||
-rw-r--r-- | lib/private/Template/CSSResourceLocator.php | 13 | ||||
-rw-r--r-- | lib/private/Template/JSResourceLocator.php | 8 | ||||
-rwxr-xr-x | lib/private/Template/ResourceLocator.php | 19 | ||||
-rw-r--r-- | lib/private/TemplateLayout.php | 43 | ||||
-rw-r--r-- | tests/lib/L10N/FactoryTest.php | 8 | ||||
-rw-r--r-- | tests/lib/L10N/L10nTest.php | 4 | ||||
-rw-r--r-- | tests/lib/Template/JSResourceLocatorTest.php | 3 | ||||
-rw-r--r-- | tests/lib/Template/ResourceLocatorTest.php | 32 |
13 files changed, 94 insertions, 81 deletions
diff --git a/lib/base.php b/lib/base.php index fa69a7d6076..7098fb19fdd 100644 --- a/lib/base.php +++ b/lib/base.php @@ -594,6 +594,7 @@ class OC { // Add default composer PSR-4 autoloader self::$composerAutoloader = require_once OC::$SERVERROOT . '/lib/composer/autoload.php'; + self::$composerAutoloader->setApcuPrefix('composer_autoload'); try { self::initPaths(); diff --git a/lib/private/AppFramework/DependencyInjection/DIContainer.php b/lib/private/AppFramework/DependencyInjection/DIContainer.php index 4c413a8ae87..462f9b978fd 100644 --- a/lib/private/AppFramework/DependencyInjection/DIContainer.php +++ b/lib/private/AppFramework/DependencyInjection/DIContainer.php @@ -79,6 +79,7 @@ use Psr\Log\LoggerInterface; * @deprecated 20.0.0 */ class DIContainer extends SimpleContainer implements IAppContainer { + private string $appName; /** * @var array @@ -94,8 +95,9 @@ class DIContainer extends SimpleContainer implements IAppContainer { * @param array $urlParams * @param ServerContainer|null $server */ - public function __construct($appName, $urlParams = [], ServerContainer $server = null) { + public function __construct(string $appName, array $urlParams = [], ServerContainer $server = null) { parent::__construct(); + $this->appName = $appName; $this['appName'] = $appName; $this['urlParams'] = $urlParams; @@ -437,6 +439,15 @@ class DIContainer extends SimpleContainer implements IAppContainer { } public function query(string $name, bool $autoload = true) { + if ($name === 'AppName' || $name === 'appName') { + return $this->appName; + } + + $isServerClass = str_starts_with($name, 'OCP\\') || str_starts_with($name, 'OC\\'); + if ($isServerClass && !$this->has($name)) { + return $this->getServer()->query($name, $autoload); + } + try { return $this->queryNoFallback($name); } catch (QueryException $firstException) { @@ -461,11 +472,11 @@ class DIContainer extends SimpleContainer implements IAppContainer { if ($this->offsetExists($name)) { return parent::query($name); - } elseif ($this['AppName'] === 'settings' && strpos($name, 'OC\\Settings\\') === 0) { + } elseif ($this->appName === 'settings' && str_starts_with($name, 'OC\\Settings\\')) { return parent::query($name); - } elseif ($this['AppName'] === 'core' && strpos($name, 'OC\\Core\\') === 0) { + } elseif ($this->appName === 'core' && str_starts_with($name, 'OC\\Core\\')) { return parent::query($name); - } elseif (strpos($name, \OC\AppFramework\App::buildAppNamespace($this['AppName']) . '\\') === 0) { + } elseif (str_starts_with($name, \OC\AppFramework\App::buildAppNamespace($this->appName) . '\\')) { return parent::query($name); } diff --git a/lib/private/L10N/Factory.php b/lib/private/L10N/Factory.php index 7fcfab37fa6..71910873db7 100644 --- a/lib/private/L10N/Factory.php +++ b/lib/private/L10N/Factory.php @@ -40,6 +40,8 @@ declare(strict_types=1); namespace OC\L10N; +use OCP\ICache; +use OCP\ICacheFactory; use OCP\IConfig; use OCP\IRequest; use OCP\IUser; @@ -94,7 +96,9 @@ class Factory implements IFactory { protected $request; /** @var IUserSession */ - protected $userSession; + protected IUserSession $userSession; + + private ICache $cache; /** @var string */ protected $serverRoot; @@ -109,11 +113,13 @@ class Factory implements IFactory { IConfig $config, IRequest $request, IUserSession $userSession, + ICacheFactory $cacheFactory, $serverRoot ) { $this->config = $config; $this->request = $request; $this->userSession = $userSession; + $this->cache = $cacheFactory->createLocal('L10NFactory'); $this->serverRoot = $serverRoot; } @@ -338,6 +344,10 @@ class Factory implements IFactory { $key = 'null'; } + if ($availableLanguages = $this->cache->get($key)) { + $this->availableLanguages[$key] = $availableLanguages; + } + // also works with null as key if (!empty($this->availableLanguages[$key])) { return $this->availableLanguages[$key]; @@ -374,6 +384,7 @@ class Factory implements IFactory { } $this->availableLanguages[$key] = $available; + $this->cache->set($key, $available, 60); return $available; } diff --git a/lib/private/Server.php b/lib/private/Server.php index 07e90843a98..d420b6fd11d 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -688,6 +688,7 @@ class Server extends ServerContainer implements IServerContainer { $c->get(\OCP\IConfig::class), $c->getRequest(), $c->get(IUserSession::class), + $c->get(ICacheFactory::class), \OC::$SERVERROOT ); }); diff --git a/lib/private/ServerContainer.php b/lib/private/ServerContainer.php index 0bc99f6c152..e53737990e8 100644 --- a/lib/private/ServerContainer.php +++ b/lib/private/ServerContainer.php @@ -139,10 +139,13 @@ class ServerContainer extends SimpleContainer { public function query(string $name, bool $autoload = true) { $name = $this->sanitizeName($name); - try { - return parent::query($name, false); - } catch (QueryException $e) { - // Continue with general autoloading then + if (str_starts_with($name, 'OCA\\')) { + // Skip server container query for app namespace classes + try { + return parent::query($name, false); + } catch (QueryException $e) { + // Continue with general autoloading then + } } // In case the service starts with OCA\ we try to find the service in diff --git a/lib/private/Template/CSSResourceLocator.php b/lib/private/Template/CSSResourceLocator.php index 2cbf12ce65d..5047b3e906f 100644 --- a/lib/private/Template/CSSResourceLocator.php +++ b/lib/private/Template/CSSResourceLocator.php @@ -34,14 +34,8 @@ namespace OC\Template; use Psr\Log\LoggerInterface; class CSSResourceLocator extends ResourceLocator { - - /** - * @param string $theme - * @param array $core_map - * @param array $party_map - */ - public function __construct(LoggerInterface $logger, $theme, $core_map, $party_map) { - parent::__construct($logger, $theme, $core_map, $party_map); + public function __construct(LoggerInterface $logger) { + parent::__construct($logger); } /** @@ -50,8 +44,7 @@ class CSSResourceLocator extends ResourceLocator { public function doFind($style) { $app = substr($style, 0, strpos($style, '/')); if (strpos($style, '3rdparty') === 0 - && $this->appendIfExist($this->thirdpartyroot, $style.'.css') - || $this->appendIfExist($this->serverroot, $style.'.css') + && $this->appendIfExist($this->serverroot, $style.'.css') || $this->appendIfExist($this->serverroot, 'core/'.$style.'.css') ) { return; diff --git a/lib/private/Template/JSResourceLocator.php b/lib/private/Template/JSResourceLocator.php index 9e76655aba2..88323af75de 100644 --- a/lib/private/Template/JSResourceLocator.php +++ b/lib/private/Template/JSResourceLocator.php @@ -34,8 +34,8 @@ class JSResourceLocator extends ResourceLocator { /** @var JSCombiner */ protected $jsCombiner; - public function __construct(LoggerInterface $logger, $theme, array $core_map, array $party_map, JSCombiner $JSCombiner) { - parent::__construct($logger, $theme, $core_map, $party_map); + public function __construct(LoggerInterface $logger, JSCombiner $JSCombiner) { + parent::__construct($logger); $this->jsCombiner = $JSCombiner; } @@ -45,10 +45,6 @@ class JSResourceLocator extends ResourceLocator { */ public function doFind($script) { $theme_dir = 'themes/'.$this->theme.'/'; - if (strpos($script, '3rdparty') === 0 - && $this->appendIfExist($this->thirdpartyroot, $script.'.js')) { - return; - } // Extracting the appId and the script file name $app = substr($script, 0, strpos($script, '/')); diff --git a/lib/private/Template/ResourceLocator.php b/lib/private/Template/ResourceLocator.php index 5a50cc6fd1b..9e6e2056e6b 100755 --- a/lib/private/Template/ResourceLocator.php +++ b/lib/private/Template/ResourceLocator.php @@ -36,25 +36,20 @@ abstract class ResourceLocator { protected $mapping; protected $serverroot; - protected $thirdpartyroot; protected $webroot; protected $resources = []; protected LoggerInterface $logger; - /** - * @param string $theme - * @param array $core_map - * @param array $party_map - */ - public function __construct(LoggerInterface $logger, $theme, $core_map, $party_map) { + public function __construct(LoggerInterface $logger) { $this->logger = $logger; - $this->theme = $theme; - $this->mapping = $core_map + $party_map; - $this->serverroot = key($core_map); - $this->thirdpartyroot = key($party_map); - $this->webroot = $this->mapping[$this->serverroot]; + $this->mapping = [ + \OC::$SERVERROOT => \OC::$WEBROOT + ]; + $this->serverroot = \OC::$SERVERROOT; + $this->webroot = \OC::$WEBROOT; + $this->theme = \OC_Util::getTheme(); } /** diff --git a/lib/private/TemplateLayout.php b/lib/private/TemplateLayout.php index e043f79745a..aa1ee203f31 100644 --- a/lib/private/TemplateLayout.php +++ b/lib/private/TemplateLayout.php @@ -44,8 +44,9 @@ namespace OC; use bantu\IniGetWrapper\IniGetWrapper; use OC\Search\SearchQuery; -use OC\Template\JSCombiner; +use OC\Template\CSSResourceLocator; use OC\Template\JSConfigHelper; +use OC\Template\JSResourceLocator; use OCP\AppFramework\Http\TemplateResponse; use OCP\Defaults; use OCP\IConfig; @@ -54,11 +55,16 @@ use OCP\INavigationManager; use OCP\IUserSession; use OCP\Support\Subscription\IRegistry; use OCP\Util; -use Psr\Log\LoggerInterface; class TemplateLayout extends \OC_Template { private static $versionHash = ''; + /** @var CSSResourceLocator|null */ + public static $cssLocator = null; + + /** @var JSResourceLocator|null */ + public static $jsLocator = null; + /** @var IConfig */ private $config; @@ -332,17 +338,11 @@ class TemplateLayout extends \OC_Template { * @return array */ public static function findStylesheetFiles($styles, $compileScss = true) { - // Read the selected theme from the config file - $theme = \OC_Util::getTheme(); - - $locator = new \OC\Template\CSSResourceLocator( - \OC::$server->get(LoggerInterface::class), - $theme, - [ \OC::$SERVERROOT => \OC::$WEBROOT ], - [ \OC::$SERVERROOT => \OC::$WEBROOT ], - ); - $locator->find($styles); - return $locator->getResources(); + if (!self::$cssLocator) { + self::$cssLocator = \OCP\Server::get(CSSResourceLocator::class); + } + self::$cssLocator->find($styles); + return self::$cssLocator->getResources(); } /** @@ -366,18 +366,11 @@ class TemplateLayout extends \OC_Template { * @return array */ public static function findJavascriptFiles($scripts) { - // Read the selected theme from the config file - $theme = \OC_Util::getTheme(); - - $locator = new \OC\Template\JSResourceLocator( - \OC::$server->get(LoggerInterface::class), - $theme, - [ \OC::$SERVERROOT => \OC::$WEBROOT ], - [ \OC::$SERVERROOT => \OC::$WEBROOT ], - \OC::$server->query(JSCombiner::class) - ); - $locator->find($scripts); - return $locator->getResources(); + if (!self::$jsLocator) { + self::$jsLocator = \OCP\Server::get(JSResourceLocator::class); + } + self::$jsLocator->find($scripts); + return self::$jsLocator->getResources(); } /** diff --git a/tests/lib/L10N/FactoryTest.php b/tests/lib/L10N/FactoryTest.php index 4e01602a4f7..7af069cbff3 100644 --- a/tests/lib/L10N/FactoryTest.php +++ b/tests/lib/L10N/FactoryTest.php @@ -13,6 +13,7 @@ namespace Test\L10N; use OC\L10N\Factory; use OC\L10N\LanguageNotFoundException; +use OCP\ICacheFactory; use OCP\IConfig; use OCP\IRequest; use OCP\IUser; @@ -32,6 +33,9 @@ class FactoryTest extends TestCase { /** @var IUserSession|MockObject */ protected $userSession; + /** @var ICacheFactory|MockObject */ + protected $cacheFactory; + /** @var string */ protected $serverRoot; @@ -41,6 +45,7 @@ class FactoryTest extends TestCase { $this->config = $this->createMock(IConfig::class); $this->request = $this->createMock(IRequest::class); $this->userSession = $this->createMock(IUserSession::class); + $this->cacheFactory = $this->createMock(ICacheFactory::class); $this->serverRoot = \OC::$SERVERROOT; } @@ -64,13 +69,14 @@ class FactoryTest extends TestCase { $this->config, $this->request, $this->userSession, + $this->cacheFactory, $this->serverRoot, ]) ->setMethods($methods) ->getMock(); } - return new Factory($this->config, $this->request, $this->userSession, $this->serverRoot); + return new Factory($this->config, $this->request, $this->userSession, $this->cacheFactory, $this->serverRoot); } public function dataFindAvailableLanguages(): array { diff --git a/tests/lib/L10N/L10nTest.php b/tests/lib/L10N/L10nTest.php index f410c523c05..f224592432c 100644 --- a/tests/lib/L10N/L10nTest.php +++ b/tests/lib/L10N/L10nTest.php @@ -11,6 +11,7 @@ namespace Test\L10N; use DateTime; use OC\L10N\Factory; use OC\L10N\L10N; +use OCP\ICacheFactory; use OCP\IConfig; use OCP\IRequest; use OCP\IUserSession; @@ -32,7 +33,8 @@ class L10nTest extends TestCase { $request = $this->createMock(IRequest::class); /** @var IUserSession $userSession */ $userSession = $this->createMock(IUserSession::class); - return new Factory($config, $request, $userSession, \OC::$SERVERROOT); + $cacheFactory = $this->createMock(ICacheFactory::class); + return new Factory($config, $request, $userSession, $cacheFactory, \OC::$SERVERROOT); } public function testSimpleTranslationWithTrailingColon(): void { diff --git a/tests/lib/Template/JSResourceLocatorTest.php b/tests/lib/Template/JSResourceLocatorTest.php index 7dedd4ad3c7..20fd79a91b5 100644 --- a/tests/lib/Template/JSResourceLocatorTest.php +++ b/tests/lib/Template/JSResourceLocatorTest.php @@ -63,9 +63,6 @@ class JSResourceLocatorTest extends \Test\TestCase { ); return new JSResourceLocator( $this->logger, - 'theme', - ['core' => 'map'], - ['3rd' => 'party'], $jsCombiner ); } diff --git a/tests/lib/Template/ResourceLocatorTest.php b/tests/lib/Template/ResourceLocatorTest.php index 0cb28843a53..fa329ca6581 100644 --- a/tests/lib/Template/ResourceLocatorTest.php +++ b/tests/lib/Template/ResourceLocatorTest.php @@ -8,6 +8,7 @@ namespace Test\Template; +use OC\SystemConfig; use OC\Template\ResourceNotFoundException; use Psr\Log\LoggerInterface; @@ -22,20 +23,23 @@ class ResourceLocatorTest extends \Test\TestCase { /** * @param string $theme - * @param array $core_map - * @param array $party_map - * @param array $appsRoots * @return \PHPUnit\Framework\MockObject\MockObject */ - public function getResourceLocator($theme, $core_map, $party_map, $appsRoots) { + public function getResourceLocator($theme) { + $systemConfig = $this->createMock(SystemConfig::class); + $systemConfig + ->expects($this->any()) + ->method('getValue') + ->with('theme', '') + ->willReturn($theme); + $this->overwriteService(SystemConfig::class, $systemConfig); return $this->getMockForAbstractClass('OC\Template\ResourceLocator', - [$this->logger, $theme, $core_map, $party_map, $appsRoots ], + [$this->logger], '', true, true, true, []); } public function testFind() { - $locator = $this->getResourceLocator('theme', - ['core' => 'map'], ['3rd' => 'party'], ['foo' => 'bar']); + $locator = $this->getResourceLocator('theme'); $locator->expects($this->once()) ->method('doFind') ->with('foo'); @@ -47,6 +51,11 @@ class ResourceLocatorTest extends \Test\TestCase { } public function testFindNotFound() { + $systemConfig = $this->createMock(SystemConfig::class); + $systemConfig->method('getValue') + ->with('theme', '') + ->willReturn('theme'); + $this->overwriteService(SystemConfig::class, $systemConfig); $locator = $this->getResourceLocator('theme', ['core' => 'map'], ['3rd' => 'party'], ['foo' => 'bar']); $locator->expects($this->once()) @@ -65,8 +74,7 @@ class ResourceLocatorTest extends \Test\TestCase { } public function testAppendIfExist() { - $locator = $this->getResourceLocator('theme', - [__DIR__ => 'map'], ['3rd' => 'party'], ['foo' => 'bar']); + $locator = $this->getResourceLocator('theme'); /** @var \OC\Template\ResourceLocator $locator */ $method = new \ReflectionMethod($locator, 'appendIfExist'); $method->setAccessible(true); @@ -75,11 +83,7 @@ class ResourceLocatorTest extends \Test\TestCase { $resource1 = [__DIR__, 'webroot', basename(__FILE__)]; $this->assertEquals([$resource1], $locator->getResources()); - $method->invoke($locator, __DIR__, basename(__FILE__)); - $resource2 = [__DIR__, 'map', basename(__FILE__)]; - $this->assertEquals([$resource1, $resource2], $locator->getResources()); - $method->invoke($locator, __DIR__, 'does-not-exist'); - $this->assertEquals([$resource1, $resource2], $locator->getResources()); + $this->assertEquals([$resource1], $locator->getResources()); } } |