diff options
author | Joas Schilling <coding@schilljs.com> | 2022-02-28 17:38:44 +0300 |
---|---|---|
committer | Joas Schilling <coding@schilljs.com> | 2022-03-14 15:46:05 +0300 |
commit | 70248946ffc41958944c8aab08329e5c385a6d0c (patch) | |
tree | f6cf9108cbabd9cbd44b56bf760111bfe1efd963 /lib | |
parent | 61fc1264f199a16ee0560769743d7cfc32140656 (diff) |
Preload devices and statuses with a single query in case of flushingtechdebt/noid/group-queries-on-pushing
Signed-off-by: Joas Schilling <coding@schilljs.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Push.php | 55 |
1 files changed, 53 insertions, 2 deletions
diff --git a/lib/Push.php b/lib/Push.php index 3c446ae..3fd323f 100644 --- a/lib/Push.php +++ b/lib/Push.php @@ -86,6 +86,10 @@ class Push { protected $userStatuses = []; /** @var array[] */ protected $userDevices = []; + /** @var string[] */ + protected $loadDevicesForUsers = []; + /** @var string[] */ + protected $loadStatusForUsers = []; public function __construct(IDBConnection $connection, INotificationManager $notificationManager, @@ -131,6 +135,26 @@ class Push { public function flushPayloads(): void { $this->deferPreparing = false; + if (!empty($this->loadDevicesForUsers)) { + $this->loadDevicesForUsers = array_unique($this->loadDevicesForUsers); + $missingDevicesFor = array_diff($this->loadDevicesForUsers, array_keys($this->userDevices)); + $newUserDevices = $this->getDevicesForUsers($missingDevicesFor); + foreach ($missingDevicesFor as $userId) { + $this->userDevices[$userId] = $newUserDevices[$userId] ?? []; + } + $this->loadDevicesForUsers = []; + } + + if (!empty($this->loadStatusForUsers)) { + $this->loadStatusForUsers = array_unique($this->loadStatusForUsers); + $missingStatusFor = array_diff($this->loadStatusForUsers, array_keys($this->userStatuses)); + $newUserStatuses = $this->userStatusManager->getUserStatuses($missingStatusFor); + foreach ($missingStatusFor as $userId) { + $this->userStatuses[$userId] = $newUserStatuses[$userId] ?? null; + } + $this->loadStatusForUsers = []; + } + if (!empty($this->notificationsToPush)) { foreach ($this->notificationsToPush as $id => $notification) { $this->pushToDevice($id, $notification); @@ -185,6 +209,8 @@ class Push { if ($this->deferPreparing) { $this->notificationsToPush[$id] = clone $notification; + $this->loadDevicesForUsers[] = $notification->getUser(); + $this->loadStatusForUsers[] = $notification->getUser(); return; } @@ -210,7 +236,7 @@ class Push { $devices = $this->getDevicesForUser($notification->getUser()); $this->userDevices[$notification->getUser()] = $devices; } else { - $devices = $this->userDevices[$notification->getUser()] ?? []; + $devices = $this->userDevices[$notification->getUser()]; } if (empty($devices)) { @@ -283,6 +309,7 @@ class Push { if ($this->deferPreparing) { $this->deletesToPush[$notificationId] = ['userId' => $userId, 'app' => $app]; + $this->loadDevicesForUsers[] = $userId; return; } @@ -292,7 +319,7 @@ class Push { $devices = $this->getDevicesForUser($userId); $this->userDevices[$userId] = $devices; } else { - $devices = $this->userDevices[$userId] ?? []; + $devices = $this->userDevices[$userId]; } if ($notificationId !== 0 && $app !== '') { @@ -572,6 +599,30 @@ class Push { } /** + * @param string[] $userIds + * @return array[] + */ + protected function getDevicesForUsers(array $userIds): array { + $query = $this->db->getQueryBuilder(); + $query->select('*') + ->from('notifications_pushhash') + ->where($query->expr()->in('uid', $query->createNamedParameter($userIds, IQueryBuilder::PARAM_STR_ARRAY))); + + $devices = []; + $result = $query->executeQuery(); + while ($row = $result->fetch()) { + if (!isset($devices[$row['uid']])) { + $devices[$row['uid']] = []; + } + $devices[$row['uid']][] = $row; + } + + $result->closeCursor(); + + return $devices; + } + + /** * @param int $tokenId * @return bool */ |