Skip to content

Commit ae8fc64

Browse files
committed
Do /keys/changes before second /sync
This will avoid races between /keys/changes and /syncs.
1 parent 5e8e56c commit ae8fc64

File tree

2 files changed

+26
-37
lines changed

2 files changed

+26
-37
lines changed

src/crypto/index.js

Lines changed: 19 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ function Crypto(baseApis, sessionStore, userId, deviceId,
6969

7070
this._olmDevice = new OlmDevice(sessionStore);
7171
this._deviceList = new DeviceList(baseApis, sessionStore, this._olmDevice);
72-
this._initialDeviceListInvalidationPending = false;
7372

7473
// the last time we did a check for the number of one-time-keys on the
7574
// server.
@@ -150,15 +149,6 @@ Crypto.prototype.init = async function() {
150149
*/
151150
Crypto.prototype.registerEventHandlers = function(eventEmitter) {
152151
const crypto = this;
153-
eventEmitter.on("sync", function(syncState, oldState, data) {
154-
try {
155-
if (syncState === "SYNCING") {
156-
crypto._onSyncCompleted(data);
157-
}
158-
} catch (e) {
159-
console.error("Error handling sync", e);
160-
}
161-
});
162152

163153
eventEmitter.on("RoomMember.membership", function(event, member, oldMembership) {
164154
try {
@@ -248,7 +238,7 @@ Crypto.prototype.uploadDeviceKeys = function() {
248238

249239
/**
250240
* Stores the current one_time_key count which will be handled later (in a call of
251-
* _onSyncCompleted). The count is e.g. coming from a /sync response.
241+
* onSyncCompleted). The count is e.g. coming from a /sync response.
252242
*
253243
* @param {Number} currentCount The current count of one_time_keys to be stored
254244
*/
@@ -837,7 +827,7 @@ Crypto.prototype.onCryptoEvent = async function(event) {
837827

838828
try {
839829
// inhibit the device list refresh for now - it will happen once we've
840-
// finished processing the sync, in _onSyncCompleted.
830+
// finished processing the sync, in onSyncCompleted.
841831
await this.setRoomEncryption(roomId, content, true);
842832
} catch (e) {
843833
console.error("Error configuring encryption in room " + roomId +
@@ -853,7 +843,7 @@ Crypto.prototype.onCryptoEvent = async function(event) {
853843
*
854844
* @param {Object} syncData the data from the 'MatrixClient.sync' event
855845
*/
856-
Crypto.prototype._onSyncCompleted = function(syncData) {
846+
Crypto.prototype.onSyncCompleted = async function(syncData) {
857847
const nextSyncToken = syncData.nextSyncToken;
858848

859849
if (!syncData.oldSyncToken) {
@@ -863,18 +853,15 @@ Crypto.prototype._onSyncCompleted = function(syncData) {
863853
// invalidate devices which have changed since then.
864854
const oldSyncToken = this._sessionStore.getEndToEndDeviceSyncToken();
865855
if (oldSyncToken !== null) {
866-
this._initialDeviceListInvalidationPending = true;
867-
this._invalidateDeviceListsSince(
868-
oldSyncToken, nextSyncToken,
869-
).catch((e) => {
856+
try {
857+
await this._invalidateDeviceListsSince(
858+
oldSyncToken, nextSyncToken,
859+
);
860+
} catch (e) {
870861
// if that failed, we fall back to invalidating everyone.
871862
console.warn("Error fetching changed device list", e);
872863
this._deviceList.invalidateAllDeviceLists();
873-
}).done(() => {
874-
this._initialDeviceListInvalidationPending = false;
875-
this._deviceList.lastKnownSyncToken = nextSyncToken;
876-
this._deviceList.refreshOutdatedDeviceLists();
877-
});
864+
}
878865
} else {
879866
// otherwise, we have to invalidate all devices for all users we
880867
// are tracking.
@@ -884,14 +871,12 @@ Crypto.prototype._onSyncCompleted = function(syncData) {
884871
}
885872
}
886873

887-
if (!this._initialDeviceListInvalidationPending) {
888-
// we can now store our sync token so that we can get an update on
889-
// restart rather than having to invalidate everyone.
890-
//
891-
// (we don't really need to do this on every sync - we could just
892-
// do it periodically)
893-
this._sessionStore.storeEndToEndDeviceSyncToken(nextSyncToken);
894-
}
874+
// we can now store our sync token so that we can get an update on
875+
// restart rather than having to invalidate everyone.
876+
//
877+
// (we don't really need to do this on every sync - we could just
878+
// do it periodically)
879+
this._sessionStore.storeEndToEndDeviceSyncToken(nextSyncToken);
895880

896881
// catch up on any new devices we got told about during the sync.
897882
this._deviceList.lastKnownSyncToken = nextSyncToken;
@@ -925,13 +910,11 @@ Crypto.prototype._invalidateDeviceListsSince = function(
925910
).then((r) => {
926911
console.log("got key changes since", oldSyncToken, ":", r.changed);
927912

928-
if (!r.changed || !Array.isArray(r.changed)) {
929-
return;
913+
if (r.changed && Array.isArray(r.changed)) {
914+
r.changed.forEach((u) => {
915+
this._deviceList.invalidateUserDeviceList(u);
916+
});
930917
}
931-
932-
r.changed.forEach((u) => {
933-
this._deviceList.invalidateUserDeviceList(u);
934-
});
935918
});
936919
};
937920

src/sync.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -634,8 +634,14 @@ SyncApi.prototype._sync = async function(syncOptions) {
634634
syncOptions.hasSyncedBefore = true;
635635
}
636636

637-
// keep emitting SYNCING -> SYNCING for clients who want to do bulk updates
638637
if (!isCachedResponse) {
638+
// tell the crypto module to do its processing. It may block (to do a
639+
// /keys/changes request).
640+
if (this.opts.crypto) {
641+
await this.opts.crypto.onSyncCompleted(syncEventData);
642+
}
643+
644+
// keep emitting SYNCING -> SYNCING for clients who want to do bulk updates
639645
this._updateSyncState("SYNCING", syncEventData);
640646

641647
// tell databases that everything is now in a consistent state and can be

0 commit comments

Comments
 (0)