From 475e810523314dd9d57c70a456d43a0f08f84d95 Mon Sep 17 00:00:00 2001 From: Krille Fear Date: Tue, 9 Nov 2021 12:37:44 +0100 Subject: [PATCH] feat: Make waiting on init db optional This can improve the start-up time of apps. The three big db reads on init are loading account data, rooms and device keys. This makes it now possible to let them run parallel (while it may depend on platform if this has any effect) and the init() method can skip awaiting them. They will be at least awaited before handling the first received sync. So the app can already display the room list before device keys are loaded and request the first sync from the server before anything else is loaded from the DB. --- lib/src/client.dart | 29 ++++++++++++++++++++++++++--- lib/src/room.dart | 1 + 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/lib/src/client.dart b/lib/src/client.dart index ec74f2cd..30372237 100644 --- a/lib/src/client.dart +++ b/lib/src/client.dart @@ -893,6 +893,10 @@ class Client extends MatrixApi { /// If one of [newToken], [newUserID], [newDeviceID], [newDeviceName] is set then /// all of them must be set! If you don't set them, this method will try to /// get them from the database. + /// + /// Set [waitForFirstSync] and [waitUntilLoadCompletedLoaded] to false to speed this + /// up. You can then wait for `roomsLoading`, `accountDataLoading` and + /// `userDeviceKeysLoading` where it is necessary. Future init({ String? newToken, Uri? newHomeserver, @@ -901,6 +905,7 @@ class Client extends MatrixApi { String? newDeviceID, String? newOlmAccount, bool waitForFirstSync = true, + bool waitUntilLoadCompletedLoaded = true, }) async { if ((newToken != null || newUserID != null || @@ -1012,11 +1017,22 @@ class Client extends MatrixApi { encryption?.pickledOlmAccount, ); } - _userDeviceKeys = await database.getUserDeviceKeys(this); - _rooms = await database.getRoomList(this); + userDeviceKeysLoading = database + .getUserDeviceKeys(this) + .then((keys) => _userDeviceKeys = keys); + roomsLoading = database.getRoomList(this).then((rooms) { + _rooms = rooms; + _sortRooms(); + }); _sortRooms(); - accountData = await database.getAccountData(); + accountDataLoading = + database.getAccountData().then((data) => accountData = data); presences.clear(); + if (waitUntilLoadCompletedLoaded) { + await userDeviceKeysLoading; + await roomsLoading; + await accountDataLoading; + } } _initLock = false; _loginState = LoginState.loggedIn; @@ -1154,6 +1170,9 @@ class Client extends MatrixApi { final database = this.database; if (database != null) { + await userDeviceKeysLoading; + await roomsLoading; + await accountDataLoading; _currentTransaction = database.transaction(() async { await _handleSync(syncResp); if (prevBatch != syncResp.nextBatch) { @@ -1648,6 +1667,10 @@ class Client extends MatrixApi { _sortLock = false; } + Future? userDeviceKeysLoading; + Future? roomsLoading; + Future? accountDataLoading; + /// A map of known device keys per user. Map get userDeviceKeys => _userDeviceKeys; Map _userDeviceKeys = {}; diff --git a/lib/src/room.dart b/lib/src/room.dart index 538d591c..d261c3c7 100644 --- a/lib/src/room.dart +++ b/lib/src/room.dart @@ -1882,6 +1882,7 @@ class Room { /// Returns all known device keys for all participants in this room. Future> getUserDeviceKeys() async { + await client.userDeviceKeysLoading; final deviceKeys = []; final users = await requestParticipants(); for (final user in users) {