Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Move to lazy panel registration during registration context
Signed-off-by: Julius Härtl <[email protected]>
  • Loading branch information
juliusknorr committed Jul 15, 2020
commit 81e559313325777649e640492cba1981aff3e54a
2 changes: 1 addition & 1 deletion apps/dashboard/templates/index.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?php
\OC_Util::addScript('dashboard', 'dashboard');
\OCP\Util::addScript('dashboard', 'dashboard');
?>
<div id="app"></div>
7 changes: 7 additions & 0 deletions lib/private/AppFramework/Bootstrap/Coordinator.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
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;
Expand All @@ -47,6 +48,9 @@ class Coordinator {
/** @var Registry */
private $registry;

/** @var IManager */
private $dashboardManager;

/** @var IEventDispatcher */
private $eventDispatcher;

Expand All @@ -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;
}
Expand Down Expand Up @@ -117,6 +123,7 @@ public function runRegistration(): void {
*/
$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);
Expand Down
35 changes: 35 additions & 0 deletions lib/private/AppFramework/Bootstrap/RegistrationContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
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;
Expand All @@ -41,6 +42,9 @@ class RegistrationContext {
/** @var array[] */
private $crashReporters = [];

/** @var array[] */
private $dashboardPanels = [];

/** @var array[] */
private $services = [];

Expand Down Expand Up @@ -93,6 +97,13 @@ public function registerCrashReporter(string $reporterClass): void {
);
}

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,
Expand Down Expand Up @@ -157,6 +168,13 @@ public function registerCrashReporter(string $appId, string $reporterClass): voi
];
}

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,
Expand Down Expand Up @@ -241,6 +259,23 @@ public function delegateCrashReporterRegistrations(array $apps, Registry $regist
}
}

/**
* @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 {
Expand Down
55 changes: 55 additions & 0 deletions lib/private/Dashboard/Manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand All @@ -40,7 +54,48 @@ public function registerPanel(IPanel $panel): void {
$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;
}
}
9 changes: 9 additions & 0 deletions lib/public/AppFramework/Bootstrap/IRegistrationContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ public function registerCapability(string $capability): void;
*/
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
*
Expand Down
6 changes: 6 additions & 0 deletions lib/public/Dashboard/IManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down
6 changes: 6 additions & 0 deletions tests/lib/AppFramework/Bootstrap/CoordinatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
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;
Expand All @@ -50,6 +51,9 @@ class CoordinatorTest extends TestCase {
/** @var Registry|MockObject */
private $crashReporterRegistry;

/** @var IManager|MockObject */
private $dashboardManager;

/** @var IEventDispatcher|MockObject */
private $eventDispatcher;

Expand All @@ -65,12 +69,14 @@ protected function setUp(): void {
$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
);
Expand Down