fix: Load multiple olm sessions from the database at once for increased performance
This commit is contained in:
parent
bbcc883777
commit
add19c73a0
|
|
@ -358,15 +358,40 @@ class OlmManager {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<OlmSession>> getOlmSessions(String senderKey) async {
|
Future<void> getOlmSessionsForDevicesFromDatabase(
|
||||||
|
List<String> senderKeys) async {
|
||||||
|
if (client.database == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final rows = await client.database
|
||||||
|
.dbGetOlmSessionsForDevices(client.id, senderKeys)
|
||||||
|
.get();
|
||||||
|
final res = <String, List<OlmSession>>{};
|
||||||
|
for (final row in rows) {
|
||||||
|
res[row.identityKey] ??= <OlmSession>[];
|
||||||
|
final sess = OlmSession.fromDb(row, client.userID);
|
||||||
|
if (sess.isValid) {
|
||||||
|
res[row.identityKey].add(sess);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (final entry in res.entries) {
|
||||||
|
_olmSessions[entry.key] = entry.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<OlmSession>> getOlmSessions(String senderKey,
|
||||||
|
{bool getFromDb = true}) async {
|
||||||
var sess = olmSessions[senderKey];
|
var sess = olmSessions[senderKey];
|
||||||
if (sess == null || sess.isEmpty) {
|
if ((getFromDb ?? true) && (sess == null || sess.isEmpty)) {
|
||||||
final sessions = await getOlmSessionsFromDatabase(senderKey);
|
final sessions = await getOlmSessionsFromDatabase(senderKey);
|
||||||
if (sessions.isEmpty) {
|
if (sessions.isEmpty) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
sess = _olmSessions[senderKey] = sessions;
|
sess = _olmSessions[senderKey] = sessions;
|
||||||
}
|
}
|
||||||
|
if (sess == null) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
sess.sort((a, b) => a.lastReceived == b.lastReceived
|
sess.sort((a, b) => a.lastReceived == b.lastReceived
|
||||||
? a.sessionId.compareTo(b.sessionId)
|
? a.sessionId.compareTo(b.sessionId)
|
||||||
: b.lastReceived.compareTo(a.lastReceived));
|
: b.lastReceived.compareTo(a.lastReceived));
|
||||||
|
|
@ -475,8 +500,10 @@ class OlmManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Map<String, dynamic>> encryptToDeviceMessagePayload(
|
Future<Map<String, dynamic>> encryptToDeviceMessagePayload(
|
||||||
DeviceKeys device, String type, Map<String, dynamic> payload) async {
|
DeviceKeys device, String type, Map<String, dynamic> payload,
|
||||||
final sess = await getOlmSessions(device.curve25519Key);
|
{bool getFromDb}) async {
|
||||||
|
final sess =
|
||||||
|
await getOlmSessions(device.curve25519Key, getFromDb: getFromDb);
|
||||||
if (sess.isEmpty) {
|
if (sess.isEmpty) {
|
||||||
throw ('No olm session found for ${device.userId}:${device.deviceId}');
|
throw ('No olm session found for ${device.userId}:${device.deviceId}');
|
||||||
}
|
}
|
||||||
|
|
@ -509,9 +536,8 @@ class OlmManager {
|
||||||
var data = <String, Map<String, Map<String, dynamic>>>{};
|
var data = <String, Map<String, Map<String, dynamic>>>{};
|
||||||
// first check if any of our sessions we want to encrypt for are in the database
|
// first check if any of our sessions we want to encrypt for are in the database
|
||||||
if (client.database != null) {
|
if (client.database != null) {
|
||||||
for (final device in deviceKeys) {
|
await getOlmSessionsForDevicesFromDatabase(
|
||||||
await getOlmSessions(device.curve25519Key);
|
deviceKeys.map((d) => d.curve25519Key).toList());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
final deviceKeysWithoutSession = List<DeviceKeys>.from(deviceKeys);
|
final deviceKeysWithoutSession = List<DeviceKeys>.from(deviceKeys);
|
||||||
deviceKeysWithoutSession.removeWhere((DeviceKeys deviceKeys) =>
|
deviceKeysWithoutSession.removeWhere((DeviceKeys deviceKeys) =>
|
||||||
|
|
@ -526,7 +552,8 @@ class OlmManager {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
data[device.userId][device.deviceId] =
|
data[device.userId][device.deviceId] =
|
||||||
await encryptToDeviceMessagePayload(device, type, payload);
|
await encryptToDeviceMessagePayload(device, type, payload,
|
||||||
|
getFromDb: false);
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
Logs().w('[LibOlm] Error encrypting to-device event', e, s);
|
Logs().w('[LibOlm] Error encrypting to-device event', e, s);
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:moor/moor.dart';
|
import 'package:moor/moor.dart';
|
||||||
import 'package:olm/olm.dart' as olm;
|
|
||||||
|
|
||||||
import '../../famedlysdk.dart' as sdk;
|
import '../../famedlysdk.dart' as sdk;
|
||||||
import '../../matrix_api.dart' as api;
|
import '../../matrix_api.dart' as api;
|
||||||
|
|
@ -197,28 +196,6 @@ class Database extends _$Database {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Map<String, List<olm.Session>>> getOlmSessions(
|
|
||||||
int clientId, String userId) async {
|
|
||||||
final raw = await getAllOlmSessions(clientId).get();
|
|
||||||
if (raw.isEmpty) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
final res = <String, List<olm.Session>>{};
|
|
||||||
for (final row in raw) {
|
|
||||||
if (!res.containsKey(row.identityKey)) {
|
|
||||||
res[row.identityKey] = [];
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
var session = olm.Session();
|
|
||||||
session.unpickle(userId, row.pickle);
|
|
||||||
res[row.identityKey].add(session);
|
|
||||||
} catch (e, s) {
|
|
||||||
Logs().e('[LibOlm] Could not unpickle olm session', e, s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<DbOutboundGroupSession> getDbOutboundGroupSession(
|
Future<DbOutboundGroupSession> getDbOutboundGroupSession(
|
||||||
int clientId, String roomId) async {
|
int clientId, String roomId) async {
|
||||||
final res = await dbGetOutboundGroupSession(clientId, roomId).get();
|
final res = await dbGetOutboundGroupSession(clientId, roomId).get();
|
||||||
|
|
|
||||||
|
|
@ -6281,6 +6281,23 @@ abstract class _$Database extends GeneratedDatabase {
|
||||||
}).map(olmSessions.mapFromRow);
|
}).map(olmSessions.mapFromRow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Selectable<DbOlmSessions> dbGetOlmSessionsForDevices(
|
||||||
|
int client_id, List<String> identity_keys) {
|
||||||
|
var $arrayStartIndex = 2;
|
||||||
|
final expandedidentity_keys =
|
||||||
|
$expandVar($arrayStartIndex, identity_keys.length);
|
||||||
|
$arrayStartIndex += identity_keys.length;
|
||||||
|
return customSelect(
|
||||||
|
'SELECT * FROM olm_sessions WHERE client_id = :client_id AND identity_key IN ($expandedidentity_keys)',
|
||||||
|
variables: [
|
||||||
|
Variable.withInt(client_id),
|
||||||
|
for (var $ in identity_keys) Variable.withString($)
|
||||||
|
],
|
||||||
|
readsFrom: {
|
||||||
|
olmSessions
|
||||||
|
}).map(olmSessions.mapFromRow);
|
||||||
|
}
|
||||||
|
|
||||||
Future<int> storeOlmSession(int client_id, String identitiy_key,
|
Future<int> storeOlmSession(int client_id, String identitiy_key,
|
||||||
String session_id, String pickle, int last_received) {
|
String session_id, String pickle, int last_received) {
|
||||||
return customInsert(
|
return customInsert(
|
||||||
|
|
|
||||||
|
|
@ -183,6 +183,7 @@ getAllUserDeviceKeysKeys: SELECT * FROM user_device_keys_key WHERE client_id = :
|
||||||
getAllUserCrossSigningKeys: SELECT * FROM user_cross_signing_keys WHERE client_id = :client_id;
|
getAllUserCrossSigningKeys: SELECT * FROM user_cross_signing_keys WHERE client_id = :client_id;
|
||||||
getAllOlmSessions: SELECT * FROM olm_sessions WHERE client_id = :client_id;
|
getAllOlmSessions: SELECT * FROM olm_sessions WHERE client_id = :client_id;
|
||||||
dbGetOlmSessions: SELECT * FROM olm_sessions WHERE client_id = :client_id AND identity_key = :identity_key;
|
dbGetOlmSessions: SELECT * FROM olm_sessions WHERE client_id = :client_id AND identity_key = :identity_key;
|
||||||
|
dbGetOlmSessionsForDevices: SELECT * FROM olm_sessions WHERE client_id = :client_id AND identity_key IN :identity_keys;
|
||||||
storeOlmSession: INSERT OR REPLACE INTO olm_sessions (client_id, identity_key, session_id, pickle, last_received) VALUES (:client_id, :identitiy_key, :session_id, :pickle, :last_received);
|
storeOlmSession: INSERT OR REPLACE INTO olm_sessions (client_id, identity_key, session_id, pickle, last_received) VALUES (:client_id, :identitiy_key, :session_id, :pickle, :last_received);
|
||||||
getAllOutboundGroupSessions: SELECT * FROM outbound_group_sessions WHERE client_id = :client_id;
|
getAllOutboundGroupSessions: SELECT * FROM outbound_group_sessions WHERE client_id = :client_id;
|
||||||
dbGetOutboundGroupSession: SELECT * FROM outbound_group_sessions WHERE client_id = :client_id AND room_id = :room_id;
|
dbGetOutboundGroupSession: SELECT * FROM outbound_group_sessions WHERE client_id = :client_id AND room_id = :room_id;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue