Remove Router static access, add caching to redis.

This commit is contained in:
Greyscale 2020-07-27 03:31:04 +02:00
parent d371e37dc1
commit 1e5b7ff188
3 changed files with 71 additions and 50 deletions

View file

@ -5,6 +5,8 @@ namespace Benzine;
use Benzine\ORM\Connection\Databases;
use Benzine\ORM\Laminator;
use Benzine\Redis\Redis;
use Benzine\Router\Route;
use Benzine\Router\Router;
use Benzine\Services\ConfigurationService;
use Benzine\Services\EnvironmentService;
use Benzine\Services\SessionService;
@ -44,6 +46,7 @@ class App
protected ConfigurationService $configurationService;
protected \Slim\App $app;
protected Logger $logger;
protected Router $router;
protected bool $isSessionsEnabled = true;
protected bool $interrogateControllersComplete = false;
private array $routePaths = [];
@ -212,10 +215,6 @@ class App
return $translator;
});
$container->set(EnvironmentService::class, function () {
return new EnvironmentService();
});
$container->set(ConfigurationService::class, function (EnvironmentService $environmentService) use ($app) {
return new ConfigurationService(
$app,
@ -278,10 +277,6 @@ class App
return $debugBar;
});
$container->set(\Middlewares\Debugbar::class, function (DebugBar $debugBar) {
return new \Middlewares\Debugbar($debugBar);
});
$container->set(\Redis::class, function (EnvironmentService $environmentService) {
$redis = new Redis();
$redis->connect(
@ -292,14 +287,6 @@ class App
return $redis;
});
$container->set(SessionService::class, function (\Redis $redis) {
return new SessionService($redis);
});
$container->set(Databases::class, function (ConfigurationService $configurationService) {
return new Databases($configurationService);
});
$container->set(Laminator::class, function (ConfigurationService $configurationService, Databases $databases) {
return new Laminator(
APP_ROOT,
@ -322,7 +309,7 @@ class App
date_default_timezone_set(self::DEFAULT_TIMEZONE);
}
$debugBar = $container->get(DebugBar::class);
$this->router = $container->get(Router::class);
return $container;
}
@ -335,7 +322,7 @@ class App
$this->app->add($container->get(\Middlewares\TrailingSlash::class));
//$this->app->add($container->get(\Middlewares\Whoops::class));
//$this->app->add($container->get(\Middlewares\Minifier::class));
$this->app->add($container->get(\Middlewares\GzipEncoder::class));
//$this->app->add($container->get(\Middlewares\GzipEncoder::class));
$this->app->add($container->get(\Middlewares\ContentLength::class));
}
@ -422,7 +409,7 @@ class App
include $path;
}
}
Router\Router::Instance()->populateRoutes($app);
$this->router->populateRoutes($app);
return $this;
}
@ -463,6 +450,26 @@ class App
return in_array($supportedLanguage, $this->supportedLanguages, true);
}
/**
* @return mixed|Router
*/
public function getRouter()
{
return $this->router;
}
/**
* @param mixed|Router $router
*
* @return App
*/
public function setRouter($router)
{
$this->router = $router;
return $this;
}
protected function interrogateTranslations(): void
{
foreach (new \DirectoryIterator(APP_ROOT.'/src/Strings') as $translationFile) {
@ -480,23 +487,24 @@ class App
}
$this->interrogateControllersComplete = true;
if ($this->router->loadCache()) {
return;
}
$controllerPaths = [
APP_ROOT.'/src/Controllers',
APP_ROOT . '/src/Controllers',
];
foreach ($controllerPaths as $controllerPath) {
//$this->logger->debug("Route Discovery - {$controllerPath}");
if (file_exists($controllerPath)) {
foreach (new \DirectoryIterator($controllerPath) as $controllerFile) {
if (!$controllerFile->isDot() && $controllerFile->isFile() && $controllerFile->isReadable()) {
//$this->logger->debug(" > {$controllerFile->getPathname()}");
$appClass = new \ReflectionClass(get_called_class());
$expectedClasses = [
$appClass->getNamespaceName().'\\Controllers\\'.str_replace('.php', '', $controllerFile->getFilename()),
'⌬\\Controllers\\'.str_replace('.php', '', $controllerFile->getFilename()),
];
foreach ($expectedClasses as $expectedClass) {
//$this->logger->debug(" > {$expectedClass}");
if (class_exists($expectedClass)) {
$rc = new \ReflectionClass($expectedClass);
if (!$rc->isAbstract()) {
@ -508,23 +516,18 @@ class App
if (false === stripos($docBlockRow, '@route')) {
continue;
}
//$this->logger->debug(" > fff {$docBlockRow}");
$route = trim(substr(
$docBlockRow,
(stripos($docBlockRow, '@route') + strlen('@route'))
));
//$this->logger->debug(" > Route {$route}");
//\Kint::dump($route);
@list($httpMethods, $path, $extra) = explode(' ', $route, 3);
//\Kint::dump($httpMethods, $path, $extra);exit;
$httpMethods = explode(',', strtoupper($httpMethods));
$options = [];
$defaultOptions = [
'access' => Router\Route::ACCESS_PUBLIC,
'access' => Route::ACCESS_PUBLIC,
'weight' => 100,
];
if (isset($extra)) {
@ -538,9 +541,8 @@ class App
}
$options = array_merge($defaultOptions, $options);
foreach ($httpMethods as $httpMethod) {
//$this->logger->debug(" > Adding {$path} to router");
$newRoute = Router\Route::Factory()
$newRoute = Route::Factory()
->setHttpMethod($httpMethod)
->setRouterPattern('/'.ltrim($path, '/'))
->setCallback($method->class.':'.$method->name)
@ -555,7 +557,7 @@ class App
}
}
Router\Router::Instance()->addRoute($newRoute);
$this->router->addRoute($newRoute);
}
}
}
@ -568,6 +570,8 @@ class App
}
}
Router\Router::Instance()->weighRoutes();
$this->router
->weighRoutes()
->cache();
}
}

View file

@ -2,29 +2,22 @@
namespace Benzine\Router;
use Cache\Adapter\Chain\CachePoolChain;
use Monolog\Logger;
use Slim\App;
class Router
{
protected static $instance;
/** @var Route[] */
protected $routes = [];
private $routes = [];
private Logger $logger;
private CachePoolChain $cachePoolChain;
private int $cacheTTL = 60;
/** @var Logger */
protected $logger;
/**
* @return Router
*/
public static function Instance()
public function __construct(\Redis $redis, Logger $logger, CachePoolChain $cachePoolChain)
{
if (!self::$instance instanceof Router) {
self::$instance = new Router();
}
return self::$instance;
$this->logger = $logger;
$this->cachePoolChain = $cachePoolChain;
}
public function weighRoutes(): Router
@ -75,4 +68,29 @@ class Router
return $this->routes;
}
public function loadCache(): bool
{
$time = microtime(true);
$cacheItem = $this->cachePoolChain->getItem('routes');
if (!$cacheItem || null === $cacheItem->get()) {
return false;
}
$this->routes = $cacheItem->get();
$this->logger->debug(sprintf('Loaded routes from Cache in %sms', number_format((microtime(true) - $time) * 1000, 2)));
return true;
}
public function cache(): Router
{
$routeItem = $this->cachePoolChain
->getItem('routes')
->set($this->getRoutes())
->expiresAfter($this->cacheTTL)
;
$this->cachePoolChain->save($routeItem);
return $this;
}
}

View file

@ -3,7 +3,6 @@
namespace Benzine\Tests;
use Benzine\App;
use Benzine\Router\Router;
use Psr\Http\Message\ResponseInterface;
use Slim\Http\Environment;
use Slim\Http\Headers;
@ -63,7 +62,7 @@ abstract class RoutesTestCase extends BaseTestCase
if (file_exists(APP_ROOT.'/src/RoutesExtra.php')) {
require APP_ROOT.'/src/RoutesExtra.php';
}
Router::Instance()->populateRoutes($slimApp);
$applicationInstance->getRouter()->populateRoutes();
$headers = array_merge($this->defaultHeaders, $extraHeaders);
$envArray = array_merge($this->defaultEnvironment, $headers);