Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
1 change: 1 addition & 0 deletions lib/composer/composer/autoload_classmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,7 @@
'OCP\\Notification\\IManager' => $baseDir . '/lib/public/Notification/IManager.php',
'OCP\\Notification\\INotification' => $baseDir . '/lib/public/Notification/INotification.php',
'OCP\\Notification\\INotifier' => $baseDir . '/lib/public/Notification/INotifier.php',
'OCP\\Notification\\IPreloadableNotifier' => $baseDir . '/lib/public/Notification/IPreloadableNotifier.php',
'OCP\\Notification\\IncompleteNotificationException' => $baseDir . '/lib/public/Notification/IncompleteNotificationException.php',
'OCP\\Notification\\IncompleteParsedNotificationException' => $baseDir . '/lib/public/Notification/IncompleteParsedNotificationException.php',
'OCP\\Notification\\InvalidValueException' => $baseDir . '/lib/public/Notification/InvalidValueException.php',
Expand Down
1 change: 1 addition & 0 deletions lib/composer/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OCP\\Notification\\IManager' => __DIR__ . '/../../..' . '/lib/public/Notification/IManager.php',
'OCP\\Notification\\INotification' => __DIR__ . '/../../..' . '/lib/public/Notification/INotification.php',
'OCP\\Notification\\INotifier' => __DIR__ . '/../../..' . '/lib/public/Notification/INotifier.php',
'OCP\\Notification\\IPreloadableNotifier' => __DIR__ . '/../../..' . '/lib/public/Notification/IPreloadableNotifier.php',
'OCP\\Notification\\IncompleteNotificationException' => __DIR__ . '/../../..' . '/lib/public/Notification/IncompleteNotificationException.php',
'OCP\\Notification\\IncompleteParsedNotificationException' => __DIR__ . '/../../..' . '/lib/public/Notification/IncompleteParsedNotificationException.php',
'OCP\\Notification\\InvalidValueException' => __DIR__ . '/../../..' . '/lib/public/Notification/InvalidValueException.php',
Expand Down
12 changes: 12 additions & 0 deletions lib/private/Notification/Manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use OCP\Notification\IncompleteParsedNotificationException;
use OCP\Notification\INotification;
use OCP\Notification\INotifier;
use OCP\Notification\IPreloadableNotifier;
use OCP\Notification\UnknownNotificationException;
use OCP\RichObjectStrings\IRichTextFormatter;
use OCP\RichObjectStrings\IValidator;
Expand Down Expand Up @@ -390,6 +391,17 @@ public function prepare(INotification $notification, string $languageCode): INot
return $notification;
}

public function preloadDataForParsing(array $notifications, string $languageCode): void {
$notifiers = $this->getNotifiers();
foreach ($notifiers as $notifier) {
if (!($notifier instanceof IPreloadableNotifier)) {
continue;
}

$notifier->preloadDataForParsing($notifications, $languageCode);
}
}

/**
* @param INotification $notification
*/
Expand Down
2 changes: 1 addition & 1 deletion lib/public/Notification/IManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
use OCP\AppFramework\Attribute\Consumable;

#[Consumable(since: '9.0.0')]
interface IManager extends IApp, INotifier {
interface IManager extends IApp, IPreloadableNotifier {
/**
* @param string $appClass The service must implement IApp, otherwise a
* \InvalidArgumentException is thrown later
Expand Down
5 changes: 5 additions & 0 deletions lib/public/Notification/INotifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@

use OCP\AppFramework\Attribute\Implementable;

/**
* Please consider implementing {@see IPreloadableNotifier} to improve performance. It allows to
* preload and cache data for many notifications at once instead of loading the data for each
* prepared notification separately.
*/
#[Implementable(since: '9.0.0')]
interface INotifier {
/**
Expand Down
31 changes: 31 additions & 0 deletions lib/public/Notification/IPreloadableNotifier.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCP\Notification;

use OCP\AppFramework\Attribute\Implementable;

/**
* Allow notifier implementations to preload and cache data for many notifications at once to
* improve performance by, for example, bundling SQL queries.
*/
#[Implementable(since: '32.0.0')]
interface IPreloadableNotifier extends INotifier {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should deprecate INotifier (but can also wait one release), to make developers more aware of the performance related improvement

Copy link
Member Author

@st3iny st3iny Aug 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rather integrate the method into the actual interface rather than deprecating it. Otherwise, Psalm will complain all the time about INotifier being deprecated and we will end up with IPreloadableNotifier becoming the base interface at some point which sounds weird.

I added a hint to INotifier though to make developers aware.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well we can not extend the base interface due to our policies
And deprecating the other one would help via psalm and IDEs that was exactly my idea to it.

If an app doesn't care they can implement the interface and do nothing in the method, but get easily rid of the deprecation?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd vote for keeping the old interface as-is because the usage is not always problematic. With documentation (manual, code in-line) we can get attention to the extending interface for apps where preloading makes sense.

/**
* This method provides a way for notifier implementations to preload and cache data for many
* notifications. The data is meant to be consumed later in the {@see INotifier::prepare()}
* method to improve performance.
*
* @since 32.0.0
*
* @param INotification[] $notifications The notifications which are about to be prepared in the next step.
* @param string $languageCode The code of the language that should be used to prepare the notification.
*/
public function preloadDataForParsing(array $notifications, string $languageCode): void;
}
Loading