Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/spreed.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJoas Schilling <213943+nickvergessen@users.noreply.github.com>2020-06-08 20:17:31 +0300
committerGitHub <noreply@github.com>2020-06-08 20:17:31 +0300
commit84108f342eeb1f6e9f23e47ba7dbab1344e6a9d8 (patch)
tree74367a354fe50400e69129aff40a75568723be64 /lib
parentdf0942146ae324212a18997b4f1844d2cb2d60ff (diff)
parentc4c2818a2a5d0b5dd65d77b21ac7e36ac5b66618 (diff)
Merge pull request #3782 from nextcloud/backport/3745/stable19
[stable19] Less database queries when parsing multiple notifications
Diffstat (limited to 'lib')
-rw-r--r--lib/Notification/Notifier.php88
1 files changed, 77 insertions, 11 deletions
diff --git a/lib/Notification/Notifier.php b/lib/Notification/Notifier.php
index c336103e6..bdacd49cb 100644
--- a/lib/Notification/Notifier.php
+++ b/lib/Notification/Notifier.php
@@ -73,6 +73,11 @@ class Notifier implements INotifier {
/** @var Definitions */
protected $definitions;
+ /** @var Room[] */
+ protected $rooms = [];
+ /** @var Participant[][] */
+ protected $participants = [];
+
public function __construct(IFactory $lFactory,
IURLGenerator $url,
Config $config,
@@ -118,6 +123,65 @@ class Notifier implements INotifier {
}
/**
+ * @param string $objectId
+ * @return Room
+ * @throws RoomNotFoundException
+ */
+ protected function getRoom(string $objectId): Room {
+ if (array_key_exists($objectId, $this->rooms)) {
+ if ($this->rooms[$objectId] === null) {
+ throw new RoomNotFoundException('Room does not exist');
+ }
+
+ return $this->rooms[$objectId];
+ }
+
+ try {
+ $room = $this->manager->getRoomByToken($objectId);
+ $this->rooms[$objectId] = $room;
+ return $room;
+ } catch (RoomNotFoundException $e) {
+ try {
+ // Before 3.2.3 the id was passed in notifications
+ $room = $this->manager->getRoomById((int) $objectId);
+ $this->rooms[$objectId] = $room;
+ return $room;
+ } catch (RoomNotFoundException $e) {
+ // Room does not exist
+ $this->rooms[$objectId] = null;
+ throw $e;
+ }
+ }
+ }
+
+ /**
+ * @param Room $room
+ * @param string $userId
+ * @return Participant
+ * @throws ParticipantNotFoundException
+ */
+ protected function getParticipant(Room $room, string $userId): Participant {
+ $roomId = $room->getId();
+ if (array_key_exists($roomId, $this->participants) && array_key_exists($userId, $this->participants[$roomId])) {
+ if ($this->participants[$roomId][$userId] === null) {
+ throw new ParticipantNotFoundException('Participant does not exist');
+ }
+
+ return $this->participants[$roomId][$userId];
+ }
+
+ try {
+ $participant = $room->getParticipant($userId);
+ $this->participants[$roomId][$userId] = $participant;
+ return $participant;
+ } catch (ParticipantNotFoundException $e) {
+ // Participant does not exist
+ $this->participants[$roomId][$userId] = null;
+ throw $e;
+ }
+ }
+
+ /**
* @param INotification $notification
* @param string $languageCode The code of the language that should be used to prepare the notification
* @return INotification
@@ -138,24 +202,26 @@ class Notifier implements INotifier {
$l = $this->lFactory->get('spreed', $languageCode);
try {
- $room = $this->manager->getRoomByToken($notification->getObjectId());
+ $room = $this->getRoom($notification->getObjectId());
} catch (RoomNotFoundException $e) {
+ // Room does not exist
+ throw new AlreadyProcessedException();
+ }
+
+ if ($this->notificationManager->isPreparingPushNotification() && $notification->getSubject() === 'call') {
+ // Skip the participant check when we generate push notifications
+ // we just looped over the participants to create the notification,
+ // they can not be removed between these 2 steps, but we can save
+ // n queries.
+ } else {
try {
- // Before 3.2.3 the id was passed in notifications
- $room = $this->manager->getRoomById((int) $notification->getObjectId());
- } catch (RoomNotFoundException $e) {
+ $participant = $this->getParticipant($room, $userId);
+ } catch (ParticipantNotFoundException $e) {
// Room does not exist
throw new AlreadyProcessedException();
}
}
- try {
- $participant = $room->getParticipant($userId);
- } catch (ParticipantNotFoundException $e) {
- // Room does not exist
- throw new AlreadyProcessedException();
- }
-
$notification
->setIcon($this->url->getAbsoluteURL($this->url->imagePath('spreed', 'app-dark.svg')))
->setLink($this->url->linkToRouteAbsolute('spreed.Page.showCall', ['token' => $room->getToken()]));