From 81e559313325777649e640492cba1981aff3e54a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Julius=20H=C3=A4rtl?= Date: Tue, 23 Jun 2020 15:23:28 +0200 Subject: [PATCH] Move to lazy panel registration during registration context MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Julius Härtl --- apps/dashboard/templates/index.php | 2 +- .../AppFramework/Bootstrap/Coordinator.php | 7 +++ .../Bootstrap/RegistrationContext.php | 35 ++++++++++++ lib/private/Dashboard/Manager.php | 55 +++++++++++++++++++ .../Bootstrap/IRegistrationContext.php | 9 +++ lib/public/Dashboard/IManager.php | 6 ++ .../Bootstrap/CoordinatorTest.php | 6 ++ 7 files changed, 119 insertions(+), 1 deletion(-) diff --git a/apps/dashboard/templates/index.php b/apps/dashboard/templates/index.php index b9e614b0f1c..bca9fa30494 100644 --- a/apps/dashboard/templates/index.php +++ b/apps/dashboard/templates/index.php @@ -1,4 +1,4 @@
diff --git a/lib/private/AppFramework/Bootstrap/Coordinator.php b/lib/private/AppFramework/Bootstrap/Coordinator.php index 3edc0f97472..358e71d7854 100644 --- a/lib/private/AppFramework/Bootstrap/Coordinator.php +++ b/lib/private/AppFramework/Bootstrap/Coordinator.php @@ -30,6 +30,7 @@ use OC_App; use OCP\AppFramework\App; use OCP\AppFramework\Bootstrap\IBootstrap; use OCP\AppFramework\QueryException; +use OCP\Dashboard\IManager; use OCP\EventDispatcher\IEventDispatcher; use OCP\ILogger; use OCP\IServerContainer; @@ -47,6 +48,9 @@ class Coordinator { /** @var Registry */ private $registry; + /** @var IManager */ + private $dashboardManager; + /** @var IEventDispatcher */ private $eventDispatcher; @@ -58,10 +62,12 @@ class Coordinator { public function __construct(IServerContainer $container, Registry $registry, + IManager $dashboardManager, IEventDispatcher $eventListener, ILogger $logger) { $this->serverContainer = $container; $this->registry = $registry; + $this->dashboardManager = $dashboardManager; $this->eventDispatcher = $eventListener; $this->logger = $logger; } @@ -117,6 +123,7 @@ class Coordinator { */ $this->registrationContext->delegateCapabilityRegistrations($apps); $this->registrationContext->delegateCrashReporterRegistrations($apps, $this->registry); + $this->registrationContext->delegateDashboardPanelRegistrations($apps, $this->dashboardManager); $this->registrationContext->delegateEventListenerRegistrations($this->eventDispatcher); $this->registrationContext->delegateContainerRegistrations($apps); $this->registrationContext->delegateMiddlewareRegistrations($apps); diff --git a/lib/private/AppFramework/Bootstrap/RegistrationContext.php b/lib/private/AppFramework/Bootstrap/RegistrationContext.php index 15b1cfa51e8..270035a2908 100644 --- a/lib/private/AppFramework/Bootstrap/RegistrationContext.php +++ b/lib/private/AppFramework/Bootstrap/RegistrationContext.php @@ -29,6 +29,7 @@ use Closure; use OC\Support\CrashReport\Registry; use OCP\AppFramework\App; use OCP\AppFramework\Bootstrap\IRegistrationContext; +use OCP\Dashboard\IManager; use OCP\EventDispatcher\IEventDispatcher; use OCP\ILogger; use Throwable; @@ -41,6 +42,9 @@ class RegistrationContext { /** @var array[] */ private $crashReporters = []; + /** @var array[] */ + private $dashboardPanels = []; + /** @var array[] */ private $services = []; @@ -93,6 +97,13 @@ class RegistrationContext { ); } + public function registerDashboardPanel(string $panelClass): void { + $this->context->registerDashboardPanel( + $this->appId, + $panelClass + ); + } + public function registerService(string $name, callable $factory, bool $shared = true): void { $this->context->registerService( $this->appId, @@ -157,6 +168,13 @@ class RegistrationContext { ]; } + public function registerDashboardPanel(string $appId, string $panelClass): void { + $this->dashboardPanels[] = [ + 'appId' => $appId, + 'class' => $panelClass + ]; + } + public function registerService(string $appId, string $name, callable $factory, bool $shared = true): void { $this->services[] = [ "appId" => $appId, @@ -241,6 +259,23 @@ class RegistrationContext { } } + /** + * @param App[] $apps + */ + public function delegateDashboardPanelRegistrations(array $apps, IManager $dashboardManager): void { + foreach ($this->dashboardPanels as $panel) { + try { + $dashboardManager->lazyRegisterPanel($panel['class']); + } catch (Throwable $e) { + $appId = $panel['appId']; + $this->logger->logException($e, [ + 'message' => "Error during dashboard registration of $appId: " . $e->getMessage(), + 'level' => ILogger::ERROR, + ]); + } + } + } + public function delegateEventListenerRegistrations(IEventDispatcher $eventDispatcher): void { foreach ($this->eventListeners as $registration) { try { diff --git a/lib/private/Dashboard/Manager.php b/lib/private/Dashboard/Manager.php index 99d8999c24a..0d149dc9a13 100644 --- a/lib/private/Dashboard/Manager.php +++ b/lib/private/Dashboard/Manager.php @@ -23,12 +23,26 @@ namespace OC\Dashboard; +use OCP\AppFramework\QueryException; use OCP\Dashboard\IManager; use OCP\Dashboard\IPanel; +use OCP\IServerContainer; class Manager implements IManager { + + /** @var array */ + private $lazyPanels = []; + + /** @var IPanel[] */ private $panels = []; + /** @var IServerContainer */ + private $serverContainer; + + public function __construct(IServerContainer $serverContainer) { + $this->serverContainer = $serverContainer; + } + /** * @inheritDoc */ @@ -40,7 +54,48 @@ class Manager implements IManager { $this->panels[$panel->getId()] = $panel; } + public function lazyRegisterPanel(string $panelClass): void { + $this->lazyPanels[] = $panelClass; + } + + public function loadLazyPanels(): void { + $classes = $this->lazyPanels; + foreach ($classes as $class) { + try { + /** @var IPanel $panel */ + $panel = $this->serverContainer->query($class); + } catch (QueryException $e) { + /* + * There is a circular dependency between the logger and the registry, so + * we can not inject it. Thus the static call. + */ + \OC::$server->getLogger()->logException($e, [ + 'message' => 'Could not load lazy dashbaord panel: ' . $e->getMessage(), + 'level' => ILogger::FATAL, + ]); + } + /** + * Try to register the loaded reporter. Theoretically it could be of a wrong + * type, so we might get a TypeError here that we should catch. + */ + try { + $this->registerPanel($panel); + } catch (Throwable $e) { + /* + * There is a circular dependency between the logger and the registry, so + * we can not inject it. Thus the static call. + */ + \OC::$server->getLogger()->logException($e, [ + 'message' => 'Could not register lazy crash reporter: ' . $e->getMessage(), + 'level' => ILogger::FATAL, + ]); + } + } + $this->lazyPanels = []; + } + public function getPanels(): array { + $this->loadLazyPanels(); return $this->panels; } } diff --git a/lib/public/AppFramework/Bootstrap/IRegistrationContext.php b/lib/public/AppFramework/Bootstrap/IRegistrationContext.php index 12367e5ed05..8ce140996b7 100644 --- a/lib/public/AppFramework/Bootstrap/IRegistrationContext.php +++ b/lib/public/AppFramework/Bootstrap/IRegistrationContext.php @@ -55,6 +55,15 @@ interface IRegistrationContext { */ public function registerCrashReporter(string $reporterClass): void; + /** + * Register an implementation of \OCP\Dashboard\IPanel that + * will handle the implementation of a dashboard panel + * + * @param string $panelClass + * @return void + * @since 20.0.0 + */ + public function registerDashboardPanel(string $panelClass): void; /** * Register a service * diff --git a/lib/public/Dashboard/IManager.php b/lib/public/Dashboard/IManager.php index a5185ae22a7..21d67407fb8 100644 --- a/lib/public/Dashboard/IManager.php +++ b/lib/public/Dashboard/IManager.php @@ -37,6 +37,12 @@ interface IManager { */ public function registerPanel(IPanel $panel): void; + /** + * @param string $panelClass + * @since 20.0.0 + */ + public function lazyRegisterPanel(string $panelClass): void; + /** * @since 20.0.0 * diff --git a/tests/lib/AppFramework/Bootstrap/CoordinatorTest.php b/tests/lib/AppFramework/Bootstrap/CoordinatorTest.php index c12e5eeb150..1fca34423d5 100644 --- a/tests/lib/AppFramework/Bootstrap/CoordinatorTest.php +++ b/tests/lib/AppFramework/Bootstrap/CoordinatorTest.php @@ -33,6 +33,7 @@ use OCP\AppFramework\Bootstrap\IBootContext; use OCP\AppFramework\Bootstrap\IBootstrap; use OCP\AppFramework\Bootstrap\IRegistrationContext; use OCP\AppFramework\QueryException; +use OCP\Dashboard\IManager; use OCP\EventDispatcher\IEventDispatcher; use OCP\ILogger; use OCP\IServerContainer; @@ -50,6 +51,9 @@ class CoordinatorTest extends TestCase { /** @var Registry|MockObject */ private $crashReporterRegistry; + /** @var IManager|MockObject */ + private $dashboardManager; + /** @var IEventDispatcher|MockObject */ private $eventDispatcher; @@ -65,12 +69,14 @@ class CoordinatorTest extends TestCase { $this->appManager = $this->createMock(IAppManager::class); $this->serverContainer = $this->createMock(IServerContainer::class); $this->crashReporterRegistry = $this->createMock(Registry::class); + $this->dashboardManager = $this->createMock(IManager::class); $this->eventDispatcher = $this->createMock(IEventDispatcher::class); $this->logger = $this->createMock(ILogger::class); $this->coordinator = new Coordinator( $this->serverContainer, $this->crashReporterRegistry, + $this->dashboardManager, $this->eventDispatcher, $this->logger ); -- 2.39.5