summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoas Schilling <coding@schilljs.com>2023-12-13 10:22:32 +0100
committerJoas Schilling <coding@schilljs.com>2024-04-09 09:53:51 +0200
commita58f4cec7890e8d4d8fecf25d8992575b3258e5e (patch)
treeebdccc9b46f6110d127a3da766d09a61da986ef1
parentc59b9b8e9f092ede21815a774370d3272b07fe57 (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.php39
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);