Merge pull request #7864 from owncloud/routing-performance

Routing performance
This commit is contained in:
Thomas Müller 2014-03-25 23:00:36 +01:00
commit 1816f43722
6 changed files with 106 additions and 27 deletions

View File

@ -7,7 +7,8 @@
*/
// Post installation check
/** @var $this OC_Router */
/** @var $this OCP\Route\IRouter */
$this->create('post_setup_check', '/post-setup-check')
->action('OC_Setup', 'postSetupCheck');

View File

@ -0,0 +1,43 @@
<?php
/**
* Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OC\Route;
class CachingRouter extends Router {
/**
* @var \OCP\ICache
*/
protected $cache;
/**
* @param \OCP\ICache $cache
*/
public function __construct($cache) {
$this->cache = $cache;
parent::__construct();
}
/**
* Generate url based on $name and $parameters
*
* @param string $name Name of the route to use.
* @param array $parameters Parameters for the route
* @param bool $absolute
* @return string
*/
public function generate($name, $parameters = array(), $absolute = false) {
$key = $name . json_encode($parameters) . $absolute;
if ($this->cache->hasKey($key)) {
return $this->cache->get($key);
} else {
$url = parent::generate($name, $parameters, $absolute);
$this->cache->set($key, $url, 3600);
return $url;
}
}
}

View File

@ -47,6 +47,8 @@ class Router implements IRouter {
protected $loaded = false;
protected $loadedApps = array();
public function __construct() {
$baseUrl = \OC_Helper::linkTo('', 'index.php');
if (!\OC::$CLI) {
@ -93,27 +95,46 @@ class Router implements IRouter {
/**
* loads the api routes
*/
public function loadRoutes() {
public function loadRoutes($app = null) {
if ($this->loaded) {
return;
}
$this->loaded = true;
foreach ($this->getRoutingFiles() as $app => $file) {
$this->useCollection($app);
require_once $file;
$collection = $this->getCollection($app);
$collection->addPrefix('/apps/' . $app);
if (is_null($app)) {
$this->loaded = true;
$routingFiles = $this->getRoutingFiles();
} else {
if (isset($this->loadedApps[$app])) {
return;
}
$file = \OC_App::getAppPath($app) . '/appinfo/routes.php';
if (file_exists($file)) {
$routingFiles = array($app => $file);
} else {
$routingFiles = array();
}
}
foreach ($routingFiles as $app => $file) {
if (!$this->loadedApps[$app]) {
$this->loadedApps[$app] = true;
$this->useCollection($app);
require_once $file;
$collection = $this->getCollection($app);
$collection->addPrefix('/apps/' . $app);
$this->root->addCollection($collection);
}
}
if (!isset($this->loadedApps['core'])) {
$this->loadedApps['core'] = true;
$this->useCollection('root');
require_once 'settings/routes.php';
require_once 'core/routes.php';
// include ocs routes
require_once 'ocs/routes.php';
$collection = $this->getCollection('ocs');
$collection->addPrefix('/ocs');
$this->root->addCollection($collection);
}
$this->useCollection('root');
require_once 'settings/routes.php';
require_once 'core/routes.php';
// include ocs routes
require_once 'ocs/routes.php';
$collection = $this->getCollection('ocs');
$collection->addPrefix('/ocs');
$this->root->addCollection($collection);
}
/**
@ -152,12 +173,21 @@ class Router implements IRouter {
}
/**
* Find the route matching $url.
* Find the route matching $url
*
* @param string $url The url to find
* @throws \Exception
*/
public function match($url) {
if (substr($url, 0, 6) === '/apps/') {
// empty string / 'apps' / $app / rest of the route
list(, , $app,) = explode('/', $url, 4);
$this->loadRoutes($app);
} else if (substr($url, 0, 6) === '/core/' or substr($url, 0, 5) === '/ocs/' or substr($url, 0, 10) === '/settings/') {
$this->loadRoutes('core');
} else {
$this->loadRoutes();
}
$matcher = new UrlMatcher($this->root, $this->context);
$parameters = $matcher->match($url);
if (isset($parameters['action'])) {
@ -196,6 +226,7 @@ class Router implements IRouter {
* @return string
*/
public function generate($name, $parameters = array(), $absolute = false) {
$this->loadRoutes();
return $this->getGenerator()->generate($name, $parameters, $absolute);
}

View File

@ -159,7 +159,15 @@ class Server extends SimpleContainer implements IServerContainer {
return new \OC\BackgroundJob\JobList($c->getDatabaseConnection(), $config);
});
$this->registerService('Router', function ($c){
$router = new \OC\Route\Router();
/**
* @var Server $c
*/
$cacheFactory = $c->getMemCacheFactory();
if ($cacheFactory->isAvailable()) {
$router = new \OC\Route\CachingRouter($cacheFactory->create('route'));
} else {
$router = new \OC\Route\Router();
}
return $router;
});
}
@ -327,7 +335,7 @@ class Server extends SimpleContainer implements IServerContainer {
/**
* Returns an \OCP\CacheFactory instance
*
* @return \OCP\CacheFactory
* @return \OCP\ICacheFactory
*/
function getMemCacheFactory() {
return $this->query('MemCacheFactory');
@ -375,8 +383,6 @@ class Server extends SimpleContainer implements IServerContainer {
* @return \OCP\Route\IRouter
*/
function getRouter(){
$router = $this->query('Router');
$router->loadRoutes();
return $router;
return $this->query('Router');
}
}

View File

@ -10,8 +10,6 @@ namespace OCP\Route;
interface IRouter {
public function __construct();
/**
* Get the files to load the routes from
*
@ -24,7 +22,7 @@ interface IRouter {
/**
* loads the api routes
*/
public function loadRoutes();
public function loadRoutes($app = null);
/**
* Sets the collection to use for adding routes

View File

@ -6,7 +6,7 @@
* See the COPYING-README file.
*/
/** @var $this OC_Router */
/** @var $this OCP\Route\IRouter */
// Settings pages
$this->create('settings_help', '/settings/help')