diff options
author | Joas Schilling <coding@schilljs.com> | 2023-12-13 10:22:32 +0100 |
---|---|---|
committer | Joas Schilling <coding@schilljs.com> | 2024-04-09 09:53:51 +0200 |
commit | a58f4cec7890e8d4d8fecf25d8992575b3258e5e (patch) | |
tree | ebdccc9b46f6110d127a3da766d09a61da986ef1 | |
parent | c59b9b8e9f092ede21815a774370d3272b07fe57 (diff) |
fix(notifications): Preparse call notifications for improved performancebugfix/11209/pre-parse-call-notifications
Signed-off-by: Joas Schilling <coding@schilljs.com>
-rw-r--r-- | lib/Notification/Listener.php | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/lib/Notification/Listener.php b/lib/Notification/Listener.php index f622dd865..123de1b6f 100644 --- a/lib/Notification/Listener.php +++ b/lib/Notification/Listener.php @@ -41,10 +41,12 @@ use OCP\AppFramework\Utility\ITimeFactory; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventDispatcher; use OCP\EventDispatcher\IEventListener; +use OCP\IConfig; use OCP\IDBConnection; use OCP\IUser; use OCP\IUserSession; use OCP\Notification\IManager; +use OCP\Notification\INotification; use Psr\Log\LoggerInterface; /** @@ -53,10 +55,14 @@ use Psr\Log\LoggerInterface; class Listener implements IEventListener { protected bool $shouldSendCallNotification = false; + /** @var array<string, INotification> $preparedCallNotifications Map of language => parsed notification in that language */ + protected array $preparedCallNotifications = []; public function __construct( + protected IConfig $serverConfig, protected IDBConnection $connection, protected IManager $notificationManager, + protected Notifier $notificationProvider, protected ParticipantService $participantsService, protected IEventDispatcher $dispatcher, protected IUserSession $userSession, @@ -290,7 +296,24 @@ class Listener implements IEventListener { return; } + $this->preparedCallNotifications = []; $userIds = $this->participantsService->getParticipantUserIdsForCallNotifications($room); + // Room name depends on the notification user for one-to-one, + // so we avoid preparsing it there. Also, it comes with some base load, + // so we only do it for "big enough" calls. + $preparseNotificationForPush = count($userIds) > 10; + if ($preparseNotificationForPush) { + $fallbackLang = $this->serverConfig->getSystemValue('force_language', null); + if (is_string($fallbackLang)) { + /** @psalm-var array<string, string> $userLanguages */ + $userLanguages = []; + } else { + $fallbackLang = $this->serverConfig->getSystemValueString('default_language', 'en'); + /** @psalm-var array<string, string> $userLanguages */ + $userLanguages = $this->serverConfig->getUserValueForUsers('core', 'lang', $userIds); + } + } + $this->connection->beginTransaction(); try { foreach ($userIds as $userId) { @@ -298,6 +321,22 @@ class Listener implements IEventListener { continue; } + if ($preparseNotificationForPush) { + // Get the settings for this particular user, then check if we have notifications to email them + $languageCode = $userLanguages[$userId] ?? $fallbackLang; + + if (!isset($this->preparedCallNotifications[$languageCode])) { + $translatedNotification = clone $notification; + + $this->notificationManager->setPreparingPushNotification(true); + $this->preparedCallNotifications[$languageCode] = $this->notificationProvider->prepare($translatedNotification, $languageCode); + $this->notificationManager->setPreparingPushNotification(false); + $notification = $translatedNotification; + } else { + $notification = $this->preparedCallNotifications[$languageCode]; + } + } + try { $notification->setUser($userId); $this->notificationManager->notify($notification); |