From bfc5eb3ee5ea749f28d6cf7bf4fbea2e04acd680 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 19 Aug 2020 16:12:49 +0200 Subject: [PATCH] return changed members from sync writer we will use it to handle race between /sync and /members and to update the member list if it loaded --- src/matrix/room/Room.js | 17 +++++++++++--- .../room/timeline/persistence/SyncWriter.js | 22 ++++++++++++++----- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/matrix/room/Room.js b/src/matrix/room/Room.js index ca7618f2..79f0b36d 100644 --- a/src/matrix/room/Room.js +++ b/src/matrix/room/Room.js @@ -36,20 +36,31 @@ export class Room extends EventEmitter { this._sendQueue = new SendQueue({roomId, storage, sendScheduler, pendingEvents}); this._timeline = null; this._user = user; + this._changedMembersDuringSync = null; } async writeSync(roomResponse, membership, txn) { const summaryChanges = this._summary.writeSync(roomResponse, membership, txn); - const {entries, newLiveKey} = await this._syncWriter.writeSync(roomResponse, txn); + const {entries, newLiveKey, changedMembers} = await this._syncWriter.writeSync(roomResponse, txn); let removedPendingEvents; if (roomResponse.timeline && roomResponse.timeline.events) { removedPendingEvents = this._sendQueue.removeRemoteEchos(roomResponse.timeline.events, txn); } - return {summaryChanges, newTimelineEntries: entries, newLiveKey, removedPendingEvents}; + return {summaryChanges, newTimelineEntries: entries, newLiveKey, removedPendingEvents, changedMembers}; } - afterSync({summaryChanges, newTimelineEntries, newLiveKey, removedPendingEvents}) { + afterSync({summaryChanges, newTimelineEntries, newLiveKey, removedPendingEvents, changedMembers}) { this._syncWriter.afterSync(newLiveKey); + if (changedMembers.length) { + if (this._changedMembersDuringSync) { + for (const member of changedMembers) { + this._changedMembersDuringSync.set(member.userId, member); + } + } + if (this._memberList) { + this._memberList.afterSync(changedMembers); + } + } if (summaryChanges) { this._summary.applyChanges(summaryChanges); this.emit("change"); diff --git a/src/matrix/room/timeline/persistence/SyncWriter.js b/src/matrix/room/timeline/persistence/SyncWriter.js index 62a2fb7e..dff28118 100644 --- a/src/matrix/room/timeline/persistence/SyncWriter.js +++ b/src/matrix/room/timeline/persistence/SyncWriter.js @@ -108,28 +108,37 @@ export class SyncWriter { // if it is there already txn.roomMembers.set(member.serialize()); } + return member; } } else { txn.roomState.set(this._roomId, event); } } - async _writeStateEvents(roomResponse, txn) { + _writeStateEvents(roomResponse, txn) { + const changedMembers = []; // persist state const {state, timeline} = roomResponse; if (state.events) { for (const event of state.events) { - await this._writeStateEvent(event, txn); + const member = this._writeStateEvent(event, txn); + if (member) { + changedMembers.push(member); + } } } // persist live state events in timeline if (timeline.events) { for (const event of timeline.events) { if (typeof event.state_key === "string") { - this._writeStateEvent(event, txn); + const member = this._writeStateEvent(event, txn); + if (member) { + changedMembers.push(member); + } } } } + return changedMembers; } _writeTimeline(entries, timeline, currentKey, txn) { @@ -165,12 +174,13 @@ export class SyncWriter { entries.push(FragmentBoundaryEntry.end(oldFragment, this._fragmentIdComparer)); entries.push(FragmentBoundaryEntry.start(newFragment, this._fragmentIdComparer)); } - - await this._writeStateEvents(roomResponse, txn); + // important this happens before _writeTimeline so + // members are available in the transaction + const changedMembers = this._writeStateEvents(roomResponse, txn); currentKey = this._writeTimeline(entries, timeline, currentKey, txn); - return {entries, newLiveKey: currentKey}; + return {entries, newLiveKey: currentKey, changedMembers}; } afterSync(newLiveKey) {