Use memcache to save the query for unread message count

For a given message id $lastReadMessage we cache the number of messages
that exist past that message, which happen to also be the number of
unread messages, because this is expensive to query per room and user repeatedly

Signed-off-by: Joas Schilling <coding@schilljs.com>
This commit is contained in:
Joas Schilling 2021-07-02 15:38:38 +02:00
Родитель 127b54fe57
Коммит ca8a3516b3
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 7076EA9751AACDDA
2 изменённых файлов: 19 добавлений и 2 удалений

Просмотреть файл

@ -77,6 +77,8 @@ class ChatManager {
protected $timeFactory;
/** @var ICache */
protected $cache;
/** @var ICache */
protected $unreadCountCache;
public function __construct(CommentsManager $commentsManager,
IEventDispatcher $dispatcher,
@ -93,6 +95,7 @@ class ChatManager {
$this->participantService = $participantService;
$this->notifier = $notifier;
$this->cache = $cacheFactory->createDistributed('talk/lastmsgid');
$this->unreadCountCache = $cacheFactory->createDistributed('talk/unreadcount');
$this->timeFactory = $timeFactory;
}
@ -140,6 +143,7 @@ class ChatManager {
// Update last_message
$chat->setLastMessage($comment);
$this->unreadCountCache->clear($chat->getId() . '-');
if ($sendNotifications) {
$this->notifier->notifyOtherParticipant($chat, $comment, []);
@ -174,6 +178,7 @@ class ChatManager {
// Update last_message
$chat->setLastMessage($comment);
$this->unreadCountCache->clear($chat->getId() . '-');
$this->dispatcher->dispatch(self::EVENT_AFTER_SYSTEM_MESSAGE_SEND, $event);
} catch (NotFoundException $e) {
@ -223,6 +228,7 @@ class ChatManager {
// Update last_message
if ($comment->getActorType() !== 'bots' || $comment->getActorId() === 'changelog') {
$chat->setLastMessage($comment);
$this->unreadCountCache->clear($chat->getId() . '-');
}
$alreadyNotifiedUsers = [];
@ -315,7 +321,18 @@ class ChatManager {
}
public function getUnreadCount(Room $chat, int $lastReadMessage): int {
return $this->commentsManager->getNumberOfCommentsForObjectSinceComment('chat', (string) $chat->getId(), $lastReadMessage, 'comment');
/**
* for a given message id $lastReadMessage we cache the number of messages
* that exist past that message, which happen to also be the number of
* unread messages, because this is expensive to query per room and user repeatedly
*/
$key = $chat->getId() . '-' . $lastReadMessage;
$unreadCount = $this->unreadCountCache->get($key);
if ($unreadCount === null) {
$unreadCount = $this->commentsManager->getNumberOfCommentsForObjectSinceComment('chat', (string) $chat->getId(), $lastReadMessage, 'comment');
$this->unreadCountCache->set($key, $unreadCount, 1800);
}
return $unreadCount;
}
/**

Просмотреть файл

@ -321,7 +321,7 @@ class ChatManagerTest extends TestCase {
public function testGetUnreadCount() {
/** @var Room|MockObject $chat */
$chat = $this->createMock(Room::class);
$chat->expects($this->once())
$chat->expects($this->atLeastOnce())
->method('getId')
->willReturn(23);