From 1eb2869fa8d034a6619546f5628c3a0bae064e16 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Mon, 24 Feb 2020 01:07:25 +0100 Subject: [PATCH] Fix stuck unread messages by storing state events in the db This may increase the db size by a factor of 1000 in the worst case and it will need some fixes, when we decide to not show some events in the timeline, but it should work for now. --- src/Cache.cpp | 49 +++++++++++++++++++++++++++++++++++++------------ src/Cache_p.h | 1 + src/Utils.cpp | 4 ++-- 3 files changed, 40 insertions(+), 14 deletions(-) diff --git a/src/Cache.cpp b/src/Cache.cpp index 1361606f..856c2942 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -43,9 +43,9 @@ static lmdb::val NEXT_BATCH_KEY("next_batch"); static lmdb::val OLM_ACCOUNT_KEY("olm_account"); static lmdb::val CACHE_FORMAT_VERSION_KEY("cache_format_version"); -constexpr size_t MAX_RESTORED_MESSAGES = 30; +constexpr size_t MAX_RESTORED_MESSAGES = 30'000; -constexpr auto DB_SIZE = 32UL * 1024UL * 1024UL * 1024ULL; // 32 GB +constexpr auto DB_SIZE = 32ULL * 1024ULL * 1024ULL * 1024ULL; // 32 GB constexpr auto MAX_DBS = 8092UL; //! Cache databases and their format. @@ -915,16 +915,17 @@ Cache::calculateRoomReadStatus(const std::string &room_id) auto txn = lmdb::txn::begin(env_); // Get last event id on the room. - const auto last_event_id = getLastMessageInfo(txn, room_id).event_id; + const auto last_event_id = getLastEventId(txn, room_id); const auto localUser = utils::localUser().toStdString(); - if (last_event_id.isEmpty()) - return false; - txn.commit(); + if (last_event_id.empty()) + return false; + // Retrieve all read receipts for that event. - const auto receipts = readReceipts(last_event_id, QString::fromStdString(room_id)); + const auto receipts = + readReceipts(QString::fromStdString(last_event_id), QString::fromStdString(room_id)); if (receipts.size() == 0) return true; @@ -1258,6 +1259,7 @@ Cache::getTimelineMentions() mtx::responses::Timeline Cache::getTimelineMessages(lmdb::txn &txn, const std::string &room_id) { + // TODO(nico): Limit the messages returned by this maybe? auto db = getMessagesDb(txn, room_id); mtx::responses::Timeline timeline; @@ -1325,6 +1327,31 @@ Cache::roomInfo(bool withInvites) return result; } +std::string +Cache::getLastEventId(lmdb::txn &txn, const std::string &room_id) +{ + auto db = getMessagesDb(txn, room_id); + + if (db.size(txn) == 0) + return {}; + + std::string timestamp, msg; + + auto cursor = lmdb::cursor::open(txn, db); + while (cursor.get(timestamp, msg, MDB_NEXT)) { + auto obj = json::parse(msg); + + if (obj.count("event") == 0) + continue; + + cursor.close(); + return obj["event"]["event_id"]; + } + cursor.close(); + + return {}; +} + DescInfo Cache::getLastMessageInfo(lmdb::txn &txn, const std::string &room_id) { @@ -1336,13 +1363,14 @@ Cache::getLastMessageInfo(lmdb::txn &txn, const std::string &room_id) std::string timestamp, msg; QSettings settings; - auto local_user = settings.value("auth/user_id").toString(); + const auto local_user = utils::localUser(); auto cursor = lmdb::cursor::open(txn, db); while (cursor.get(timestamp, msg, MDB_NEXT)) { auto obj = json::parse(msg); - if (obj.count("event") == 0) + if (obj.count("event") == 0 || !(obj["event"]["type"] == "m.room.message" || + obj["event"]["type"] == "m.sticker")) continue; mtx::events::collections::TimelineEvent event; @@ -1937,9 +1965,6 @@ Cache::saveTimelineMessages(lmdb::txn &txn, using namespace mtx::events::state; for (const auto &e : res.events) { - if (isStateEvent(e)) - continue; - if (std::holds_alternative>(e)) continue; diff --git a/src/Cache_p.h b/src/Cache_p.h index 137408b9..14ceafe8 100644 --- a/src/Cache_p.h +++ b/src/Cache_p.h @@ -250,6 +250,7 @@ private: QString getInviteRoomTopic(lmdb::txn &txn, lmdb::dbi &statesdb); QString getInviteRoomAvatarUrl(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb); + std::string getLastEventId(lmdb::txn &txn, const std::string &room_id); DescInfo getLastMessageInfo(lmdb::txn &txn, const std::string &room_id); void saveTimelineMessages(lmdb::txn &txn, const std::string &room_id, diff --git a/src/Utils.cpp b/src/Utils.cpp index a185a207..33b75894 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -17,6 +17,7 @@ #include "Cache.h" #include "Config.h" +#include "MatrixClient.h" using TimelineEvent = mtx::events::collections::TimelineEvents; @@ -44,8 +45,7 @@ createDescriptionInfo(const Event &event, const QString &localUser, const QStrin QString utils::localUser() { - QSettings settings; - return settings.value("auth/user_id").toString(); + return QString::fromStdString(http::client()->user_id().to_string()); } QString