summary refs log tree commit diff
diff options
context:
space:
mode:
authorNicolas Werner <nicolas.werner@hotmail.de>2020-11-25 23:43:31 +0100
committerNicolas Werner <nicolas.werner@hotmail.de>2020-11-25 23:54:25 +0100
commitc31b9e27939a2f756056a818d83c64c9e43b721d (patch)
treeae7b274ea984b419be0dc48cb585a4ea369243d3
parentAdd some db logging and clean up avatar urls a bit (diff)
downloadnheko-c31b9e27939a2f756056a818d83c64c9e43b721d.tar.xz
Fix race when reading members from db
-rw-r--r--src/Cache.cpp27
-rw-r--r--src/ChatPage.cpp15
-rw-r--r--src/Utils.cpp30
-rw-r--r--src/Utils.h4
-rw-r--r--src/timeline/TimelineModel.cpp5
5 files changed, 52 insertions, 29 deletions
diff --git a/src/Cache.cpp b/src/Cache.cpp

index bd0f3733..be9af8ee 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp
@@ -1162,10 +1162,10 @@ Cache::saveState(const mtx::responses::Sync &res) saveTimelineMessages(txn, room.first, room.second.timeline); RoomInfo updatedInfo; - updatedInfo.name = getRoomName(txn, statesdb, membersdb).toStdString(); - updatedInfo.topic = getRoomTopic(txn, statesdb).toStdString(); + updatedInfo.name = getRoomName(txn, statesdb, membersdb).toStdString(); + updatedInfo.topic = getRoomTopic(txn, statesdb).toStdString(); updatedInfo.avatar_url = getRoomAvatarUrl(txn, statesdb, membersdb).toStdString(); - updatedInfo.version = getRoomVersion(txn, statesdb).toStdString(); + updatedInfo.version = getRoomVersion(txn, statesdb).toStdString(); // Process the account_data associated with this room if (!room.second.account_data.events.empty()) { @@ -1808,6 +1808,17 @@ Cache::getLastMessageInfo(lmdb::txn &txn, const std::string &room_id) e.what()); return {}; } + auto membersdb{0}; + + try { + membersdb = getMembersDb(txn, room_id); + } catch (lmdb::runtime_error &e) { + nhlog::db()->error("Can't open db for room '{}', probably doesn't exist yet. ({})", + room_id, + e.what()); + return {}; + } + if (orderDb.size(txn) == 0) return DescInfo{}; @@ -1850,9 +1861,16 @@ Cache::getLastMessageInfo(lmdb::txn &txn, const std::string &room_id) mtx::events::collections::TimelineEvent te; mtx::events::collections::from_json(obj, te); + lmdb::val info; + MemberInfo m; + if (lmdb::dbi_get( + txn, membersdb, lmdb::val(obj["sender"].get<std::string>()), info)) { + m = json::parse(std::string_view(info.data(), info.size())); + } + cursor.close(); return utils::getMessageDescription( - te.data, local_user, QString::fromStdString(room_id)); + te.data, local_user, QString::fromStdString(m.name)); } cursor.close(); @@ -1911,7 +1929,6 @@ Cache::getRoomAvatarUrl(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersd // Resolve avatar for 1-1 chats. while (cursor.get(user_id, member_data, MDB_NEXT)) { - try { MemberInfo m = json::parse(member_data); if (user_id == localUserId_.toStdString()) { diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp
index 1fd9b9bc..6dfa62ef 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp
@@ -20,7 +20,6 @@ #include <QMessageBox> #include <QSettings> #include <QShortcut> -#include <QtConcurrent> #include <mtx/responses.hpp> @@ -281,10 +280,12 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QWidget *parent) &ChatPage::setGroupViewState); connect(this, &ChatPage::initializeRoomList, room_list_, &RoomList::initialize); - connect(this, - &ChatPage::initializeViews, - view_manager_, - [this](const mtx::responses::Rooms &rooms) { view_manager_->sync(rooms); }); + connect( + this, + &ChatPage::initializeViews, + view_manager_, + [this](const mtx::responses::Rooms &rooms) { view_manager_->sync(rooms); }, + Qt::QueuedConnection); connect(this, &ChatPage::initializeEmptyViews, view_manager_, @@ -522,8 +523,6 @@ ChatPage::bootstrap(QString userid, QString homeserver, QString token) void ChatPage::loadStateFromCache() { - emit contentLoaded(); - nhlog::db()->info("restoring state from cache"); try { @@ -555,6 +554,8 @@ ChatPage::loadStateFromCache() getProfileInfo(); + emit contentLoaded(); + // Start receiving events. emit trySyncCb(); } diff --git a/src/Utils.cpp b/src/Utils.cpp
index 2896e773..743c393f 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp
@@ -27,12 +27,12 @@ QHash<QString, QString> authorColors_; template<class T, class Event> static DescInfo -createDescriptionInfo(const Event &event, const QString &localUser, const QString &room_id) +createDescriptionInfo(const Event &event, const QString &localUser, const QString &displayName) { const auto msg = std::get<T>(event); const auto sender = QString::fromStdString(msg.sender); - const auto username = cache::displayName(room_id, sender); + const auto username = displayName; const auto ts = QDateTime::fromMSecsSinceEpoch(msg.origin_server_ts); return DescInfo{QString::fromStdString(msg.event_id), @@ -153,7 +153,7 @@ utils::descriptiveTime(const QDateTime &then) DescInfo utils::getMessageDescription(const TimelineEvent &event, const QString &localUser, - const QString &room_id) + const QString &displayName) { using Audio = mtx::events::RoomEvent<mtx::events::msg::Audio>; using Emote = mtx::events::RoomEvent<mtx::events::msg::Emote>; @@ -168,31 +168,31 @@ utils::getMessageDescription(const TimelineEvent &event, using Encrypted = mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>; if (std::holds_alternative<Audio>(event)) { - return createDescriptionInfo<Audio>(event, localUser, room_id); + return createDescriptionInfo<Audio>(event, localUser, displayName); } else if (std::holds_alternative<Emote>(event)) { - return createDescriptionInfo<Emote>(event, localUser, room_id); + return createDescriptionInfo<Emote>(event, localUser, displayName); } else if (std::holds_alternative<File>(event)) { - return createDescriptionInfo<File>(event, localUser, room_id); + return createDescriptionInfo<File>(event, localUser, displayName); } else if (std::holds_alternative<Image>(event)) { - return createDescriptionInfo<Image>(event, localUser, room_id); + return createDescriptionInfo<Image>(event, localUser, displayName); } else if (std::holds_alternative<Notice>(event)) { - return createDescriptionInfo<Notice>(event, localUser, room_id); + return createDescriptionInfo<Notice>(event, localUser, displayName); } else if (std::holds_alternative<Text>(event)) { - return createDescriptionInfo<Text>(event, localUser, room_id); + return createDescriptionInfo<Text>(event, localUser, displayName); } else if (std::holds_alternative<Video>(event)) { - return createDescriptionInfo<Video>(event, localUser, room_id); + return createDescriptionInfo<Video>(event, localUser, displayName); } else if (std::holds_alternative<CallInvite>(event)) { - return createDescriptionInfo<CallInvite>(event, localUser, room_id); + return createDescriptionInfo<CallInvite>(event, localUser, displayName); } else if (std::holds_alternative<CallAnswer>(event)) { - return createDescriptionInfo<CallAnswer>(event, localUser, room_id); + return createDescriptionInfo<CallAnswer>(event, localUser, displayName); } else if (std::holds_alternative<CallHangUp>(event)) { - return createDescriptionInfo<CallHangUp>(event, localUser, room_id); + return createDescriptionInfo<CallHangUp>(event, localUser, displayName); } else if (std::holds_alternative<mtx::events::Sticker>(event)) { - return createDescriptionInfo<mtx::events::Sticker>(event, localUser, room_id); + return createDescriptionInfo<mtx::events::Sticker>(event, localUser, displayName); } else if (auto msg = std::get_if<Encrypted>(&event); msg != nullptr) { const auto sender = QString::fromStdString(msg->sender); - const auto username = cache::displayName(room_id, sender); + const auto username = displayName; const auto ts = QDateTime::fromMSecsSinceEpoch(msg->origin_server_ts); DescInfo info; diff --git a/src/Utils.h b/src/Utils.h
index f59e8673..6de3d458 100644 --- a/src/Utils.h +++ b/src/Utils.h
@@ -67,7 +67,9 @@ descriptiveTime(const QDateTime &then); //! Generate a message description from the event to be displayed //! in the RoomList. DescInfo -getMessageDescription(const TimelineEvent &event, const QString &localUser, const QString &room_id); +getMessageDescription(const TimelineEvent &event, + const QString &localUser, + const QString &displayName); //! Get the first character of a string, taking into account that //! surrogate pairs might be in use. diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp
index 4cbd5777..53791c98 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp
@@ -709,7 +709,10 @@ TimelineModel::updateLastMessage() continue; auto description = utils::getMessageDescription( - *event, QString::fromStdString(http::client()->user_id().to_string()), room_id_); + *event, + QString::fromStdString(http::client()->user_id().to_string()), + cache::displayName(room_id_, + QString::fromStdString(mtx::accessors::sender(*event)))); emit manager_->updateRoomsLastMessage(room_id_, description); return; }