From: Lukas Reschke Date: Fri, 9 Jan 2015 17:31:39 +0000 (+0100) Subject: Cache responses from the AppStore server X-Git-Tag: v8.0.0alpha2~7^2 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=b8b4df5425e25403e77b108333faa2251b1348b3;p=nextcloud-server.git Cache responses from the AppStore server Otherwise every time the AppStore was opened a lot of connections to the AppStore server were made which resulted in a terrible performance. This changeset will cache the response for a sensible time so that only the first request will be somewhat slow. Performance changes: - Loading a category took previously more than 3 seconds on my machine. Now for every follow-up request it takes less than 200ms, resulting in a performance gain of 1950% - Loading the category list took previously about 750ms - now it takes 154ms, a total performance gain of 395% --- diff --git a/lib/private/ocsclient.php b/lib/private/ocsclient.php index 351027d8018..7ce6723128b 100644 --- a/lib/private/ocsclient.php +++ b/lib/private/ocsclient.php @@ -147,7 +147,7 @@ class OC_OCSClient{ $app['changed']=strtotime($tmp[$i]->changed); $app['description']=(string)$tmp[$i]->description; $app['score']=(string)$tmp[$i]->score; - $app['downloads'] = $tmp[$i]->downloads; + $app['downloads'] = (int)$tmp[$i]->downloads; $apps[]=$app; } diff --git a/settings/ajax/disableapp.php b/settings/ajax/disableapp.php index c1e5bc8eac7..1a133ea9af7 100644 --- a/settings/ajax/disableapp.php +++ b/settings/ajax/disableapp.php @@ -10,5 +10,9 @@ if (!array_key_exists('appid', $_POST)) { $appId = $_POST['appid']; $appId = OC_App::cleanAppId($appId); +// FIXME: Clear the cache - move that into some sane helper method +\OC::$server->getMemCacheFactory()->create('settings')->remove('listApps-0'); +\OC::$server->getMemCacheFactory()->create('settings')->remove('listApps-1'); + OC_App::disable($appId); OC_JSON::success(); diff --git a/settings/ajax/enableapp.php b/settings/ajax/enableapp.php index 81ca1e0338d..88abff487db 100644 --- a/settings/ajax/enableapp.php +++ b/settings/ajax/enableapp.php @@ -7,6 +7,9 @@ $groups = isset($_POST['groups']) ? $_POST['groups'] : null; try { OC_App::enable(OC_App::cleanAppId($_POST['appid']), $groups); + // FIXME: Clear the cache - move that into some sane helper method + \OC::$server->getMemCacheFactory()->create('settings')->remove('listApps-0'); + \OC::$server->getMemCacheFactory()->create('settings')->remove('listApps-1'); OC_JSON::success(); } catch (Exception $e) { OC_Log::write('core', $e->getMessage(), OC_Log::ERROR); diff --git a/settings/ajax/installapp.php b/settings/ajax/installapp.php index 80bc1819724..f25e68214a7 100644 --- a/settings/ajax/installapp.php +++ b/settings/ajax/installapp.php @@ -12,6 +12,9 @@ $appId = OC_App::cleanAppId($appId); $result = OC_App::installApp($appId); if($result !== false) { + // FIXME: Clear the cache - move that into some sane helper method + \OC::$server->getMemCacheFactory()->create('settings')->remove('listApps-0'); + \OC::$server->getMemCacheFactory()->create('settings')->remove('listApps-1'); OC_JSON::success(array('data' => array('appid' => $appId))); } else { $l = \OC::$server->getL10N('settings'); diff --git a/settings/ajax/uninstallapp.php b/settings/ajax/uninstallapp.php index cae7c33f292..e50fc31a449 100644 --- a/settings/ajax/uninstallapp.php +++ b/settings/ajax/uninstallapp.php @@ -12,6 +12,9 @@ $appId = OC_App::cleanAppId($appId); $result = OC_App::removeApp($appId); if($result !== false) { + // FIXME: Clear the cache - move that into some sane helper method + \OC::$server->getMemCacheFactory()->create('settings')->remove('listApps-0'); + \OC::$server->getMemCacheFactory()->create('settings')->remove('listApps-1'); OC_JSON::success(array('data' => array('appid' => $appId))); } else { $l = \OC::$server->getL10N('settings'); diff --git a/settings/application.php b/settings/application.php index 070da8024b2..f7ba72f3bfc 100644 --- a/settings/application.php +++ b/settings/application.php @@ -55,7 +55,8 @@ class Application extends App { $c->query('AppName'), $c->query('Request'), $c->query('L10N'), - $c->query('Config') + $c->query('Config'), + $c->query('ICacheFactory') ); }); $container->registerService('SecuritySettingsController', function(IContainer $c) { @@ -120,6 +121,9 @@ class Application extends App { $container->registerService('Config', function(IContainer $c) { return $c->query('ServerContainer')->getConfig(); }); + $container->registerService('ICacheFactory', function(IContainer $c) { + return $c->query('ServerContainer')->getMemCacheFactory(); + }); $container->registerService('L10N', function(IContainer $c) { return $c->query('ServerContainer')->getL10N('settings'); }); diff --git a/settings/controller/appsettingscontroller.php b/settings/controller/appsettingscontroller.php index 3688859ef56..55677d64870 100644 --- a/settings/controller/appsettingscontroller.php +++ b/settings/controller/appsettingscontroller.php @@ -14,6 +14,7 @@ namespace OC\Settings\Controller; use OC\App\DependencyAnalyzer; use OC\App\Platform; use \OCP\AppFramework\Controller; +use OCP\ICacheFactory; use OCP\IRequest; use OCP\IL10N; use OCP\IConfig; @@ -27,20 +28,25 @@ class AppSettingsController extends Controller { private $l10n; /** @var IConfig */ private $config; + /** @var \OCP\ICache */ + private $cache; /** * @param string $appName * @param IRequest $request * @param IL10N $l10n * @param IConfig $config + * @param ICacheFactory $cache */ public function __construct($appName, IRequest $request, IL10N $l10n, - IConfig $config) { + IConfig $config, + ICacheFactory $cache) { parent::__construct($appName, $request); $this->l10n = $l10n; $this->config = $config; + $this->cache = $cache->create($appName); } /** @@ -49,13 +55,16 @@ class AppSettingsController extends Controller { */ public function listCategories() { - $categories = array( - array('id' => 0, 'displayName' => (string)$this->l10n->t('Enabled') ), - array('id' => 1, 'displayName' => (string)$this->l10n->t('Not enabled') ), - ); + if(!is_null($this->cache->get('listCategories'))) { + return $this->cache->get('listCategories'); + } + $categories = [ + ['id' => 0, 'displayName' => (string)$this->l10n->t('Enabled')], + ['id' => 1, 'displayName' => (string)$this->l10n->t('Not enabled')], + ]; if($this->config->getSystemValue('appstoreenabled', true)) { - $categories[] = array('id' => 2, 'displayName' => (string)$this->l10n->t('Recommended') ); + $categories[] = ['id' => 2, 'displayName' => (string)$this->l10n->t('Recommended')]; // apps from external repo via OCS $ocs = \OC_OCSClient::getCategories(); foreach($ocs as $k => $v) { @@ -67,6 +76,7 @@ class AppSettingsController extends Controller { } $categories['status'] = 'success'; + $this->cache->set('listCategories', $categories, 3600); return $categories; } @@ -77,44 +87,46 @@ class AppSettingsController extends Controller { * @return array */ public function listApps($category = 0) { - $apps = array(); - - switch($category) { - // installed apps - case 0: - $apps = \OC_App::listAllApps(true); - $apps = array_filter($apps, function($app) { - return $app['active']; - }); - break; - // not-installed apps - case 1: - $apps = \OC_App::listAllApps(true); - $apps = array_filter($apps, function($app) { - return !$app['active']; - }); - break; - default: - if ($category === 2) { - $apps = \OC_App::getAppstoreApps('approved'); - $apps = array_filter($apps, function($app) { - return isset($app['internalclass']) && $app['internalclass'] === 'recommendedapp'; + if(!is_null($this->cache->get('listApps-'.$category))) { + $apps = $this->cache->get('listApps-'.$category); + } else { + switch ($category) { + // installed apps + case 0: + $apps = \OC_App::listAllApps(true); + $apps = array_filter($apps, function ($app) { + return $app['active']; + }); + break; + // not-installed apps + case 1: + $apps = \OC_App::listAllApps(true); + $apps = array_filter($apps, function ($app) { + return !$app['active']; }); - } else { - $apps = \OC_App::getAppstoreApps('approved', $category); - } - if (!$apps) { - $apps = array(); - } - usort($apps, function ($a, $b) { - $a = (int)$a['score']; - $b = (int)$b['score']; - if ($a === $b) { - return 0; + break; + default: + if ($category === 2) { + $apps = \OC_App::getAppstoreApps('approved'); + $apps = array_filter($apps, function ($app) { + return isset($app['internalclass']) && $app['internalclass'] === 'recommendedapp'; + }); + } else { + $apps = \OC_App::getAppstoreApps('approved', $category); + } + if (!$apps) { + $apps = array(); } - return ($a > $b) ? -1 : 1; - }); - break; + usort($apps, function ($a, $b) { + $a = (int)$a['score']; + $b = (int)$b['score']; + if ($a === $b) { + return 0; + } + return ($a > $b) ? -1 : 1; + }); + break; + } } // fix groups to be an array @@ -142,6 +154,8 @@ class AppSettingsController extends Controller { return $app; }, $apps); - return array('apps' => $apps, 'status' => 'success'); + $this->cache->set('listApps-'.$category, $apps, 300); + + return ['apps' => $apps, 'status' => 'success']; } }