mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-22 11:00:48 +03:00
Fix race when reading members from db
This commit is contained in:
parent
7cda502edd
commit
c31b9e2793
5 changed files with 52 additions and 29 deletions
|
@ -1162,10 +1162,10 @@ Cache::saveState(const mtx::responses::Sync &res)
|
||||||
saveTimelineMessages(txn, room.first, room.second.timeline);
|
saveTimelineMessages(txn, room.first, room.second.timeline);
|
||||||
|
|
||||||
RoomInfo updatedInfo;
|
RoomInfo updatedInfo;
|
||||||
updatedInfo.name = getRoomName(txn, statesdb, membersdb).toStdString();
|
updatedInfo.name = getRoomName(txn, statesdb, membersdb).toStdString();
|
||||||
updatedInfo.topic = getRoomTopic(txn, statesdb).toStdString();
|
updatedInfo.topic = getRoomTopic(txn, statesdb).toStdString();
|
||||||
updatedInfo.avatar_url = getRoomAvatarUrl(txn, statesdb, membersdb).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
|
// Process the account_data associated with this room
|
||||||
if (!room.second.account_data.events.empty()) {
|
if (!room.second.account_data.events.empty()) {
|
||||||
|
@ -1808,6 +1808,17 @@ Cache::getLastMessageInfo(lmdb::txn &txn, const std::string &room_id)
|
||||||
e.what());
|
e.what());
|
||||||
return {};
|
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)
|
if (orderDb.size(txn) == 0)
|
||||||
return DescInfo{};
|
return DescInfo{};
|
||||||
|
|
||||||
|
@ -1850,9 +1861,16 @@ Cache::getLastMessageInfo(lmdb::txn &txn, const std::string &room_id)
|
||||||
mtx::events::collections::TimelineEvent te;
|
mtx::events::collections::TimelineEvent te;
|
||||||
mtx::events::collections::from_json(obj, 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();
|
cursor.close();
|
||||||
return utils::getMessageDescription(
|
return utils::getMessageDescription(
|
||||||
te.data, local_user, QString::fromStdString(room_id));
|
te.data, local_user, QString::fromStdString(m.name));
|
||||||
}
|
}
|
||||||
cursor.close();
|
cursor.close();
|
||||||
|
|
||||||
|
@ -1911,7 +1929,6 @@ Cache::getRoomAvatarUrl(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersd
|
||||||
|
|
||||||
// Resolve avatar for 1-1 chats.
|
// Resolve avatar for 1-1 chats.
|
||||||
while (cursor.get(user_id, member_data, MDB_NEXT)) {
|
while (cursor.get(user_id, member_data, MDB_NEXT)) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
MemberInfo m = json::parse(member_data);
|
MemberInfo m = json::parse(member_data);
|
||||||
if (user_id == localUserId_.toStdString()) {
|
if (user_id == localUserId_.toStdString()) {
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QShortcut>
|
#include <QShortcut>
|
||||||
#include <QtConcurrent>
|
|
||||||
|
|
||||||
#include <mtx/responses.hpp>
|
#include <mtx/responses.hpp>
|
||||||
|
|
||||||
|
@ -281,10 +280,12 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QWidget *parent)
|
||||||
&ChatPage::setGroupViewState);
|
&ChatPage::setGroupViewState);
|
||||||
|
|
||||||
connect(this, &ChatPage::initializeRoomList, room_list_, &RoomList::initialize);
|
connect(this, &ChatPage::initializeRoomList, room_list_, &RoomList::initialize);
|
||||||
connect(this,
|
connect(
|
||||||
&ChatPage::initializeViews,
|
this,
|
||||||
view_manager_,
|
&ChatPage::initializeViews,
|
||||||
[this](const mtx::responses::Rooms &rooms) { view_manager_->sync(rooms); });
|
view_manager_,
|
||||||
|
[this](const mtx::responses::Rooms &rooms) { view_manager_->sync(rooms); },
|
||||||
|
Qt::QueuedConnection);
|
||||||
connect(this,
|
connect(this,
|
||||||
&ChatPage::initializeEmptyViews,
|
&ChatPage::initializeEmptyViews,
|
||||||
view_manager_,
|
view_manager_,
|
||||||
|
@ -522,8 +523,6 @@ ChatPage::bootstrap(QString userid, QString homeserver, QString token)
|
||||||
void
|
void
|
||||||
ChatPage::loadStateFromCache()
|
ChatPage::loadStateFromCache()
|
||||||
{
|
{
|
||||||
emit contentLoaded();
|
|
||||||
|
|
||||||
nhlog::db()->info("restoring state from cache");
|
nhlog::db()->info("restoring state from cache");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -555,6 +554,8 @@ ChatPage::loadStateFromCache()
|
||||||
|
|
||||||
getProfileInfo();
|
getProfileInfo();
|
||||||
|
|
||||||
|
emit contentLoaded();
|
||||||
|
|
||||||
// Start receiving events.
|
// Start receiving events.
|
||||||
emit trySyncCb();
|
emit trySyncCb();
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,12 +27,12 @@ QHash<QString, QString> authorColors_;
|
||||||
|
|
||||||
template<class T, class Event>
|
template<class T, class Event>
|
||||||
static DescInfo
|
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 msg = std::get<T>(event);
|
||||||
const auto sender = QString::fromStdString(msg.sender);
|
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);
|
const auto ts = QDateTime::fromMSecsSinceEpoch(msg.origin_server_ts);
|
||||||
|
|
||||||
return DescInfo{QString::fromStdString(msg.event_id),
|
return DescInfo{QString::fromStdString(msg.event_id),
|
||||||
|
@ -153,7 +153,7 @@ utils::descriptiveTime(const QDateTime &then)
|
||||||
DescInfo
|
DescInfo
|
||||||
utils::getMessageDescription(const TimelineEvent &event,
|
utils::getMessageDescription(const TimelineEvent &event,
|
||||||
const QString &localUser,
|
const QString &localUser,
|
||||||
const QString &room_id)
|
const QString &displayName)
|
||||||
{
|
{
|
||||||
using Audio = mtx::events::RoomEvent<mtx::events::msg::Audio>;
|
using Audio = mtx::events::RoomEvent<mtx::events::msg::Audio>;
|
||||||
using Emote = mtx::events::RoomEvent<mtx::events::msg::Emote>;
|
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>;
|
using Encrypted = mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>;
|
||||||
|
|
||||||
if (std::holds_alternative<Audio>(event)) {
|
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)) {
|
} 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)) {
|
} 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)) {
|
} 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)) {
|
} 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)) {
|
} 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)) {
|
} 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)) {
|
} 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)) {
|
} 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)) {
|
} 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)) {
|
} 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) {
|
} else if (auto msg = std::get_if<Encrypted>(&event); msg != nullptr) {
|
||||||
const auto sender = QString::fromStdString(msg->sender);
|
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);
|
const auto ts = QDateTime::fromMSecsSinceEpoch(msg->origin_server_ts);
|
||||||
|
|
||||||
DescInfo info;
|
DescInfo info;
|
||||||
|
|
|
@ -67,7 +67,9 @@ descriptiveTime(const QDateTime &then);
|
||||||
//! Generate a message description from the event to be displayed
|
//! Generate a message description from the event to be displayed
|
||||||
//! in the RoomList.
|
//! in the RoomList.
|
||||||
DescInfo
|
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
|
//! Get the first character of a string, taking into account that
|
||||||
//! surrogate pairs might be in use.
|
//! surrogate pairs might be in use.
|
||||||
|
|
|
@ -709,7 +709,10 @@ TimelineModel::updateLastMessage()
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto description = utils::getMessageDescription(
|
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);
|
emit manager_->updateRoomsLastMessage(room_id_, description);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue