mirror of
https://github.com/nextcloud/server.git
synced 2026-04-15 22:11:17 -04:00
feat(router): Cache routes in local cache if possible
This is not ideal because serializing the routecollection is not easy. It seems Symfony has its own way of doing things by dumping routes to a PHP file, maybe that would be better, but it would mean pulling a new symfony dependency and maybe refactor our Router. Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
This commit is contained in:
parent
5488f7e8b1
commit
ee3abdd81b
1 changed files with 59 additions and 0 deletions
|
|
@ -15,6 +15,7 @@ use OCP\IConfig;
|
|||
use OCP\IRequest;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
|
||||
class CachingRouter extends Router {
|
||||
protected ICache $cache;
|
||||
|
|
@ -54,4 +55,62 @@ class CachingRouter extends Router {
|
|||
return $url;
|
||||
}
|
||||
}
|
||||
|
||||
private function serializeRouteCollection(RouteCollection $collection): array {
|
||||
return array_map(
|
||||
fn (Route $route) => [$route->getPath(), $route->getDefaults(), $route->getRequirements(), $route->getOptions(), $route->getHost(), $route->getSchemes(), $route->getMethods(), $route->getCondition()],
|
||||
$collection->all(),
|
||||
);
|
||||
}
|
||||
|
||||
private function unserializeRouteCollection(array $data): RouteCollection {
|
||||
$collection = new RouteCollection();
|
||||
foreach ($data as $name => $details) {
|
||||
$route = new Route(...$details);
|
||||
$collection->add($name, $route);
|
||||
}
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the routes
|
||||
*
|
||||
* @param null|string $app
|
||||
*/
|
||||
public function loadRoutes($app = null): void {
|
||||
$this->eventLogger->start('cacheroute:load:' . $app, 'Loading Routes (using cache) for ' . $app);
|
||||
if (is_string($app)) {
|
||||
$app = $this->appManager->cleanAppId($app);
|
||||
}
|
||||
|
||||
$requestedApp = $app;
|
||||
if ($this->loaded) {
|
||||
$this->eventLogger->end('cacheroute:load:' . $app);
|
||||
return;
|
||||
}
|
||||
if (is_null($app)) {
|
||||
$cachedRoutes = $this->cache->get('root:');
|
||||
if ($cachedRoutes) {
|
||||
$this->root = $this->unserializeRouteCollection($cachedRoutes);
|
||||
$this->loaded = true;
|
||||
$this->eventLogger->end('cacheroute:load:' . $app);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (isset($this->loadedApps[$app])) {
|
||||
$this->eventLogger->end('cacheroute:load:' . $app);
|
||||
return;
|
||||
}
|
||||
$cachedRoutes = $this->cache->get('root:' . $requestedApp);
|
||||
if ($cachedRoutes) {
|
||||
$this->root = $this->unserializeRouteCollection($cachedRoutes);
|
||||
$this->loadedApps[$app] = true;
|
||||
$this->eventLogger->end('cacheroute:load:' . $app);
|
||||
return;
|
||||
}
|
||||
}
|
||||
parent::loadRoutes($app);
|
||||
$this->cache->set('root:' . $requestedApp, $this->serializeRouteCollection($this->root), 3600);
|
||||
$this->eventLogger->end('cacheroute:load:' . $app);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue