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
This commit is contained in:
Bruno Windels 2020-08-19 16:12:49 +02:00
parent a5595570f9
commit bfc5eb3ee5
2 changed files with 30 additions and 9 deletions

View file

@ -36,20 +36,31 @@ export class Room extends EventEmitter {
this._sendQueue = new SendQueue({roomId, storage, sendScheduler, pendingEvents}); this._sendQueue = new SendQueue({roomId, storage, sendScheduler, pendingEvents});
this._timeline = null; this._timeline = null;
this._user = user; this._user = user;
this._changedMembersDuringSync = null;
} }
async writeSync(roomResponse, membership, txn) { async writeSync(roomResponse, membership, txn) {
const summaryChanges = this._summary.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; let removedPendingEvents;
if (roomResponse.timeline && roomResponse.timeline.events) { if (roomResponse.timeline && roomResponse.timeline.events) {
removedPendingEvents = this._sendQueue.removeRemoteEchos(roomResponse.timeline.events, txn); 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); 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) { if (summaryChanges) {
this._summary.applyChanges(summaryChanges); this._summary.applyChanges(summaryChanges);
this.emit("change"); this.emit("change");

View file

@ -108,28 +108,37 @@ export class SyncWriter {
// if it is there already // if it is there already
txn.roomMembers.set(member.serialize()); txn.roomMembers.set(member.serialize());
} }
return member;
} }
} else { } else {
txn.roomState.set(this._roomId, event); txn.roomState.set(this._roomId, event);
} }
} }
async _writeStateEvents(roomResponse, txn) { _writeStateEvents(roomResponse, txn) {
const changedMembers = [];
// persist state // persist state
const {state, timeline} = roomResponse; const {state, timeline} = roomResponse;
if (state.events) { if (state.events) {
for (const event of 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 // persist live state events in timeline
if (timeline.events) { if (timeline.events) {
for (const event of timeline.events) { for (const event of timeline.events) {
if (typeof event.state_key === "string") { 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) { _writeTimeline(entries, timeline, currentKey, txn) {
@ -165,12 +174,13 @@ export class SyncWriter {
entries.push(FragmentBoundaryEntry.end(oldFragment, this._fragmentIdComparer)); entries.push(FragmentBoundaryEntry.end(oldFragment, this._fragmentIdComparer));
entries.push(FragmentBoundaryEntry.start(newFragment, this._fragmentIdComparer)); entries.push(FragmentBoundaryEntry.start(newFragment, this._fragmentIdComparer));
} }
// important this happens before _writeTimeline so
await this._writeStateEvents(roomResponse, txn); // members are available in the transaction
const changedMembers = this._writeStateEvents(roomResponse, txn);
currentKey = this._writeTimeline(entries, timeline, currentKey, txn); currentKey = this._writeTimeline(entries, timeline, currentKey, txn);
return {entries, newLiveKey: currentKey}; return {entries, newLiveKey: currentKey, changedMembers};
} }
afterSync(newLiveKey) { afterSync(newLiveKey) {