Fix bug where cache was initialized twice in a row

This commit is contained in:
Konstantinos Sideris 2018-06-12 20:36:16 +03:00
parent 36cb62748b
commit a97528b432
4 changed files with 89 additions and 60 deletions

View file

@ -152,6 +152,7 @@ private:
void tryInitialSync(); void tryInitialSync();
void trySync(); void trySync();
void ensureOneTimeKeyCount(const std::map<std::string, uint16_t> &counts); void ensureOneTimeKeyCount(const std::map<std::string, uint16_t> &counts);
void getProfileInfo();
//! Check if the given room is currently open. //! Check if the given room is currently open.
bool isRoomActive(const QString &room_id) bool isRoomActive(const QString &room_id)

View file

@ -87,7 +87,6 @@ init(const QString &user_id)
qRegisterMetaType<QMap<QString, RoomInfo>>(); qRegisterMetaType<QMap<QString, RoomInfo>>();
qRegisterMetaType<std::map<QString, RoomInfo>>(); qRegisterMetaType<std::map<QString, RoomInfo>>();
if (!instance_)
instance_ = std::make_unique<Cache>(user_id); instance_ = std::make_unique<Cache>(user_id);
} }
@ -113,14 +112,16 @@ Cache::Cache(const QString &userId, QObject *parent)
, outboundMegolmSessionDb_{0} , outboundMegolmSessionDb_{0}
, outboundOlmSessionDb_{0} , outboundOlmSessionDb_{0}
, localUserId_{userId} , localUserId_{userId}
{} {
setup();
}
void void
Cache::setup() Cache::setup()
{ {
log::db()->debug("setting up cache"); log::db()->debug("setting up cache");
auto statePath = QString("%1/%2/state") auto statePath = QString("%1/%2")
.arg(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)) .arg(QStandardPaths::writableLocation(QStandardPaths::CacheLocation))
.arg(QString::fromUtf8(localUserId_.toUtf8().toHex())); .arg(QString::fromUtf8(localUserId_.toUtf8().toHex()));
@ -558,10 +559,11 @@ Cache::nextBatchToken() const
void void
Cache::deleteData() Cache::deleteData()
{ {
log::db()->info("deleting data"); // TODO: We need to remove the env_ while not accepting new requests.
if (!cacheDirectory_.isEmpty()) {
if (!cacheDirectory_.isEmpty())
QDir(cacheDirectory_).removeRecursively(); QDir(cacheDirectory_).removeRecursively();
log::db()->info("deleted cache files from disk");
}
} }
bool bool
@ -575,7 +577,7 @@ Cache::isFormatValid()
txn.commit(); txn.commit();
if (!res) if (!res)
return false; return true;
std::string stored_version(current_version.data(), current_version.size()); std::string stored_version(current_version.data(), current_version.size());

View file

@ -696,69 +696,28 @@ ChatPage::bootstrap(QString userid, QString homeserver, QString token)
http::v2::client()->set_server(homeserver.toStdString()); http::v2::client()->set_server(homeserver.toStdString());
http::v2::client()->set_access_token(token.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 // The Olm client needs the user_id & device_id that will be included
// in the generated payloads & keys. // in the generated payloads & keys.
olm::client()->set_user_id(http::v2::client()->user_id().to_string()); olm::client()->set_user_id(http::v2::client()->user_id().to_string());
olm::client()->set_device_id(http::v2::client()->device_id()); olm::client()->set_device_id(http::v2::client()->device_id());
try {
cache::init(userid); cache::init(userid);
try { const bool isInitialized = cache::client()->isInitialized();
cache::client()->setup(); const bool isValid = cache::client()->isFormatValid();
if (!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()->deleteData();
cache::client()->setup();
cache::client()->setCurrentFormat();
}
if (cache::client()->isInitialized()) { cache::init(userid);
cache::client()->setCurrentFormat();
} else if (isInitialized) {
loadStateFromCache(); loadStateFromCache();
// TODO: Bootstrap olm client with saved data.
return; return;
} }
} catch (const lmdb::error &e) { } catch (const lmdb::error &e) {
@ -783,6 +742,7 @@ ChatPage::bootstrap(QString userid, QString homeserver, QString token)
return; return;
} }
getProfileInfo();
tryInitialSync(); tryInitialSync();
} }
@ -858,6 +818,8 @@ ChatPage::loadStateFromCache()
{ {
log::db()->info("restoring state from cache"); log::db()->info("restoring state from cache");
getProfileInfo();
QtConcurrent::run([this]() { QtConcurrent::run([this]() {
try { try {
cache::client()->restoreSessions(); cache::client()->restoreSessions();
@ -1315,3 +1277,53 @@ ChatPage::ensureOneTimeKeyCount(const std::map<std::string, uint16_t> &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();
}

View file

@ -17,6 +17,7 @@
#include <QApplication> #include <QApplication>
#include <QDesktopWidget> #include <QDesktopWidget>
#include <QDir>
#include <QFile> #include <QFile>
#include <QFontDatabase> #include <QFontDatabase>
#include <QLabel> #include <QLabel>
@ -48,6 +49,17 @@ screenCenter(int width, int height)
return QPoint(x, y); 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 int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
@ -112,6 +124,8 @@ main(int argc, char *argv[])
http::init(); http::init();
createCacheDirectory();
try { try {
log::init(QString("%1/nheko.log") log::init(QString("%1/nheko.log")
.arg(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)) .arg(QStandardPaths::writableLocation(QStandardPaths::CacheLocation))