Speedup sending encrypted messages after metasync was reenabled
Calling fsync everytime we save to the db is slow, which is actually fairly noticeable in some larger E2EE rooms. Speed that up slightly by batching the olm session persisting.
This commit is contained in:
parent
ee1a219661
commit
676a6506cb
|
@ -912,6 +912,29 @@ Cache::getMegolmSessionData(const MegolmSessionIndex &index)
|
||||||
// OLM sessions.
|
// OLM sessions.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
void
|
||||||
|
Cache::saveOlmSessions(std::vector<std::pair<std::string, mtx::crypto::OlmSessionPtr>> sessions,
|
||||||
|
uint64_t timestamp)
|
||||||
|
{
|
||||||
|
using namespace mtx::crypto;
|
||||||
|
|
||||||
|
auto txn = lmdb::txn::begin(env_);
|
||||||
|
for (const auto &[curve25519, session] : sessions) {
|
||||||
|
auto db = getOlmSessionsDb(txn, curve25519);
|
||||||
|
|
||||||
|
const auto pickled = pickle<SessionObject>(session.get(), pickle_secret_);
|
||||||
|
const auto session_id = mtx::crypto::session_id(session.get());
|
||||||
|
|
||||||
|
StoredOlmSession stored_session;
|
||||||
|
stored_session.pickled_session = pickled;
|
||||||
|
stored_session.last_message_ts = timestamp;
|
||||||
|
|
||||||
|
db.put(txn, session_id, nlohmann::json(stored_session).dump());
|
||||||
|
}
|
||||||
|
|
||||||
|
txn.commit();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Cache::saveOlmSession(const std::string &curve25519,
|
Cache::saveOlmSession(const std::string &curve25519,
|
||||||
mtx::crypto::OlmSessionPtr session,
|
mtx::crypto::OlmSessionPtr session,
|
||||||
|
|
|
@ -277,6 +277,8 @@ public:
|
||||||
void saveOlmSession(const std::string &curve25519,
|
void saveOlmSession(const std::string &curve25519,
|
||||||
mtx::crypto::OlmSessionPtr session,
|
mtx::crypto::OlmSessionPtr session,
|
||||||
uint64_t timestamp);
|
uint64_t timestamp);
|
||||||
|
void saveOlmSessions(std::vector<std::pair<std::string, mtx::crypto::OlmSessionPtr>> sessions,
|
||||||
|
uint64_t timestamp);
|
||||||
std::vector<std::string> getOlmSessions(const std::string &curve25519);
|
std::vector<std::string> getOlmSessions(const std::string &curve25519);
|
||||||
std::optional<mtx::crypto::OlmSessionPtr>
|
std::optional<mtx::crypto::OlmSessionPtr>
|
||||||
getOlmSession(const std::string &curve25519, const std::string &session_id);
|
getOlmSession(const std::string &curve25519, const std::string &session_id);
|
||||||
|
|
|
@ -1299,6 +1299,10 @@ send_encrypted_to_device_messages(const std::map<std::string, std::vector<std::s
|
||||||
|
|
||||||
auto our_curve = olm::client()->identity_keys().curve25519;
|
auto our_curve = olm::client()->identity_keys().curve25519;
|
||||||
|
|
||||||
|
{
|
||||||
|
auto currentTime = QDateTime::currentSecsSinceEpoch();
|
||||||
|
std::vector<std::pair<std::string, mtx::crypto::OlmSessionPtr>> sessionsToPersist;
|
||||||
|
|
||||||
for (const auto &[user, devices] : targets) {
|
for (const auto &[user, devices] : targets) {
|
||||||
auto deviceKeys = cache::client()->userKeys(user);
|
auto deviceKeys = cache::client()->userKeys(user);
|
||||||
|
|
||||||
|
@ -1324,7 +1328,7 @@ send_encrypted_to_device_messages(const std::map<std::string, std::vector<std::s
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto d = deviceKeys->device_keys.at(device);
|
const auto &d = deviceKeys->device_keys.at(device);
|
||||||
|
|
||||||
if (!d.keys.count("curve25519:" + device) || !d.keys.count("ed25519:" + device)) {
|
if (!d.keys.count("curve25519:" + device) || !d.keys.count("ed25519:" + device)) {
|
||||||
nhlog::crypto()->warn("Skipping device {} since it has no keys!", device);
|
nhlog::crypto()->warn("Skipping device {} since it has no keys!", device);
|
||||||
|
@ -1340,7 +1344,6 @@ send_encrypted_to_device_messages(const std::map<std::string, std::vector<std::s
|
||||||
|
|
||||||
auto session = cache::getLatestOlmSession(device_curve);
|
auto session = cache::getLatestOlmSession(device_curve);
|
||||||
if (!session || force_new_session) {
|
if (!session || force_new_session) {
|
||||||
auto currentTime = QDateTime::currentSecsSinceEpoch();
|
|
||||||
if (rateLimit.value(QPair(user, device)) + 60 * 60 * 10 < currentTime) {
|
if (rateLimit.value(QPair(user, device)) + 60 * 60 * 10 < currentTime) {
|
||||||
claims.one_time_keys[user][device] = mtx::crypto::SIGNED_CURVE25519;
|
claims.one_time_keys[user][device] = mtx::crypto::SIGNED_CURVE25519;
|
||||||
pks[user][device].ed25519 = d.keys.at("ed25519:" + device);
|
pks[user][device].ed25519 = d.keys.at("ed25519:" + device);
|
||||||
|
@ -1364,13 +1367,15 @@ send_encrypted_to_device_messages(const std::map<std::string, std::vector<std::s
|
||||||
d.keys.at("ed25519:" + device),
|
d.keys.at("ed25519:" + device),
|
||||||
device_curve)
|
device_curve)
|
||||||
.get<mtx::events::msg::OlmEncrypted>();
|
.get<mtx::events::msg::OlmEncrypted>();
|
||||||
|
sessionsToPersist.emplace_back(d.keys.at("curve25519:" + device),
|
||||||
|
std::move(*session));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sessionsToPersist.empty()) {
|
||||||
try {
|
try {
|
||||||
nhlog::crypto()->debug("Updated olm session: {}",
|
nhlog::crypto()->debug("Updated olm sessions: {}", sessionsToPersist.size());
|
||||||
mtx::crypto::session_id(session->get()));
|
cache::client()->saveOlmSessions(std::move(sessionsToPersist), currentTime);
|
||||||
cache::saveOlmSession(d.keys.at("curve25519:" + device),
|
|
||||||
std::move(*session),
|
|
||||||
QDateTime::currentMSecsSinceEpoch());
|
|
||||||
} catch (const lmdb::error &e) {
|
} catch (const lmdb::error &e) {
|
||||||
nhlog::db()->critical("failed to save outbound olm session: {}", e.what());
|
nhlog::db()->critical("failed to save outbound olm session: {}", e.what());
|
||||||
} catch (const mtx::crypto::olm_exception &e) {
|
} catch (const mtx::crypto::olm_exception &e) {
|
||||||
|
@ -1395,6 +1400,9 @@ send_encrypted_to_device_messages(const std::map<std::string, std::vector<std::s
|
||||||
mtx::http::RequestErr) {
|
mtx::http::RequestErr) {
|
||||||
std::map<mtx::identifiers::User, std::map<std::string, mtx::events::msg::OlmEncrypted>>
|
std::map<mtx::identifiers::User, std::map<std::string, mtx::events::msg::OlmEncrypted>>
|
||||||
messages;
|
messages;
|
||||||
|
auto currentTime = QDateTime::currentSecsSinceEpoch();
|
||||||
|
std::vector<std::pair<std::string, mtx::crypto::OlmSessionPtr>> sessionsToPersist;
|
||||||
|
|
||||||
for (const auto &[user_id, retrieved_devices] : res.one_time_keys) {
|
for (const auto &[user_id, retrieved_devices] : res.one_time_keys) {
|
||||||
nhlog::net()->debug("claimed keys for {}", user_id);
|
nhlog::net()->debug("claimed keys for {}", user_id);
|
||||||
if (retrieved_devices.size() == 0) {
|
if (retrieved_devices.size() == 0) {
|
||||||
|
@ -1440,11 +1448,16 @@ send_encrypted_to_device_messages(const std::map<std::string, std::vector<std::s
|
||||||
session.get(), ev_json, UserId(user_id), sign_key, id_key)
|
session.get(), ev_json, UserId(user_id), sign_key, id_key)
|
||||||
.get<mtx::events::msg::OlmEncrypted>();
|
.get<mtx::events::msg::OlmEncrypted>();
|
||||||
|
|
||||||
|
sessionsToPersist.emplace_back(id_key, std::move(session));
|
||||||
|
}
|
||||||
|
nhlog::net()->info("send_to_device: {}", user_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sessionsToPersist.empty()) {
|
||||||
try {
|
try {
|
||||||
nhlog::crypto()->debug("Updated olm session: {}",
|
nhlog::crypto()->debug("Updated (new) olm sessions: {}",
|
||||||
mtx::crypto::session_id(session.get()));
|
sessionsToPersist.size());
|
||||||
cache::saveOlmSession(
|
cache::client()->saveOlmSessions(std::move(sessionsToPersist), currentTime);
|
||||||
id_key, std::move(session), QDateTime::currentMSecsSinceEpoch());
|
|
||||||
} catch (const lmdb::error &e) {
|
} catch (const lmdb::error &e) {
|
||||||
nhlog::db()->critical("failed to save outbound olm session: {}", e.what());
|
nhlog::db()->critical("failed to save outbound olm session: {}", e.what());
|
||||||
} catch (const mtx::crypto::olm_exception &e) {
|
} catch (const mtx::crypto::olm_exception &e) {
|
||||||
|
@ -1452,8 +1465,6 @@ send_encrypted_to_device_messages(const std::map<std::string, std::vector<std::s
|
||||||
e.what());
|
e.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nhlog::net()->info("send_to_device: {}", user_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!messages.empty())
|
if (!messages.empty())
|
||||||
http::client()->send_to_device<mtx::events::msg::OlmEncrypted>(
|
http::client()->send_to_device<mtx::events::msg::OlmEncrypted>(
|
||||||
|
|
Loading…
Reference in New Issue