From a97528b4322a3f114134722f8a4243b2938db6fd Mon Sep 17 00:00:00 2001 From: Konstantinos Sideris Date: Tue, 12 Jun 2018 20:36:16 +0300 Subject: [PATCH] Fix bug where cache was initialized twice in a row --- include/ChatPage.h | 1 + src/Cache.cc | 18 +++---- src/ChatPage.cc | 116 +++++++++++++++++++++++++-------------------- src/main.cc | 14 ++++++ 4 files changed, 89 insertions(+), 60 deletions(-) diff --git a/include/ChatPage.h b/include/ChatPage.h index d8582993..ffea2914 100644 --- a/include/ChatPage.h +++ b/include/ChatPage.h @@ -152,6 +152,7 @@ private: void tryInitialSync(); void trySync(); void ensureOneTimeKeyCount(const std::map &counts); + void getProfileInfo(); //! Check if the given room is currently open. bool isRoomActive(const QString &room_id) diff --git a/src/Cache.cc b/src/Cache.cc index 48b1fdaf..abc6fae4 100644 --- a/src/Cache.cc +++ b/src/Cache.cc @@ -87,8 +87,7 @@ init(const QString &user_id) qRegisterMetaType>(); qRegisterMetaType>(); - if (!instance_) - instance_ = std::make_unique(user_id); + instance_ = std::make_unique(user_id); } Cache * @@ -113,14 +112,16 @@ Cache::Cache(const QString &userId, QObject *parent) , outboundMegolmSessionDb_{0} , outboundOlmSessionDb_{0} , localUserId_{userId} -{} +{ + setup(); +} void Cache::setup() { log::db()->debug("setting up cache"); - auto statePath = QString("%1/%2/state") + auto statePath = QString("%1/%2") .arg(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)) .arg(QString::fromUtf8(localUserId_.toUtf8().toHex())); @@ -558,10 +559,11 @@ Cache::nextBatchToken() const void Cache::deleteData() { - log::db()->info("deleting data"); - - if (!cacheDirectory_.isEmpty()) + // TODO: We need to remove the env_ while not accepting new requests. + if (!cacheDirectory_.isEmpty()) { QDir(cacheDirectory_).removeRecursively(); + log::db()->info("deleted cache files from disk"); + } } bool @@ -575,7 +577,7 @@ Cache::isFormatValid() txn.commit(); if (!res) - return false; + return true; std::string stored_version(current_version.data(), current_version.size()); diff --git a/src/ChatPage.cc b/src/ChatPage.cc index 3f43831c..c10d4aa2 100644 --- a/src/ChatPage.cc +++ b/src/ChatPage.cc @@ -696,69 +696,28 @@ ChatPage::bootstrap(QString userid, QString homeserver, QString token) http::v2::client()->set_server(homeserver.toStdString()); http::v2::client()->set_access_token(token.toStdString()); - http::v2::client()->get_profile( - userid.toStdString(), - [this](const mtx::responses::Profile &res, mtx::http::RequestErr err) { - if (err) { - log::net()->warn("failed to retrieve own profile info"); - return; - } - - emit setUserDisplayName(QString::fromStdString(res.display_name)); - - if (cache::client()) { - auto data = cache::client()->image(res.avatar_url); - if (!data.isNull()) { - emit setUserAvatar(QImage::fromData(data)); - return; - } - } - - if (res.avatar_url.empty()) - return; - - http::v2::client()->download( - res.avatar_url, - [this, res](const std::string &data, - const std::string &, - const std::string &, - mtx::http::RequestErr err) { - if (err) { - log::net()->warn( - "failed to download user avatar: {} - {}", - mtx::errors::to_string(err->matrix_error.errcode), - err->matrix_error.error); - return; - } - - if (cache::client()) - cache::client()->saveImage(res.avatar_url, data); - - emit setUserAvatar( - QImage::fromData(QByteArray(data.data(), data.size()))); - }); - }); - // TODO http::client()->getOwnCommunities(); // The Olm client needs the user_id & device_id that will be included // in the generated payloads & keys. olm::client()->set_user_id(http::v2::client()->user_id().to_string()); olm::client()->set_device_id(http::v2::client()->device_id()); - cache::init(userid); - try { - cache::client()->setup(); + cache::init(userid); - if (!cache::client()->isFormatValid()) { + const bool isInitialized = cache::client()->isInitialized(); + const bool isValid = cache::client()->isFormatValid(); + + if (isInitialized && !isValid) { + log::db()->warn("breaking changes in cache"); + // TODO: Deleting session data but keep using the + // same device doesn't work. cache::client()->deleteData(); - cache::client()->setup(); - cache::client()->setCurrentFormat(); - } - if (cache::client()->isInitialized()) { + cache::init(userid); + cache::client()->setCurrentFormat(); + } else if (isInitialized) { loadStateFromCache(); - // TODO: Bootstrap olm client with saved data. return; } } catch (const lmdb::error &e) { @@ -783,6 +742,7 @@ ChatPage::bootstrap(QString userid, QString homeserver, QString token) return; } + getProfileInfo(); tryInitialSync(); } @@ -858,6 +818,8 @@ ChatPage::loadStateFromCache() { log::db()->info("restoring state from cache"); + getProfileInfo(); + QtConcurrent::run([this]() { try { cache::client()->restoreSessions(); @@ -1315,3 +1277,53 @@ ChatPage::ensureOneTimeKeyCount(const std::map &counts) } } } + +void +ChatPage::getProfileInfo() +{ + QSettings settings; + const auto userid = settings.value("auth/user_id").toString().toStdString(); + + http::v2::client()->get_profile( + userid, [this](const mtx::responses::Profile &res, mtx::http::RequestErr err) { + if (err) { + log::net()->warn("failed to retrieve own profile info"); + return; + } + + emit setUserDisplayName(QString::fromStdString(res.display_name)); + + if (cache::client()) { + auto data = cache::client()->image(res.avatar_url); + if (!data.isNull()) { + emit setUserAvatar(QImage::fromData(data)); + return; + } + } + + if (res.avatar_url.empty()) + return; + + http::v2::client()->download( + res.avatar_url, + [this, res](const std::string &data, + const std::string &, + const std::string &, + mtx::http::RequestErr err) { + if (err) { + log::net()->warn( + "failed to download user avatar: {} - {}", + mtx::errors::to_string(err->matrix_error.errcode), + err->matrix_error.error); + return; + } + + if (cache::client()) + cache::client()->saveImage(res.avatar_url, data); + + emit setUserAvatar( + QImage::fromData(QByteArray(data.data(), data.size()))); + }); + }); + // TODO http::client()->getOwnCommunities(); +} diff --git a/src/main.cc b/src/main.cc index 13a712f4..0a127962 100644 --- a/src/main.cc +++ b/src/main.cc @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -48,6 +49,17 @@ screenCenter(int width, int height) return QPoint(x, y); } +void +createCacheDirectory() +{ + auto dir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation); + + if (!QDir().mkpath(dir)) { + throw std::runtime_error( + ("Unable to create state directory:" + dir).toStdString().c_str()); + } +} + int main(int argc, char *argv[]) { @@ -112,6 +124,8 @@ main(int argc, char *argv[]) http::init(); + createCacheDirectory(); + try { log::init(QString("%1/nheko.log") .arg(QStandardPaths::writableLocation(QStandardPaths::CacheLocation))