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._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");

View file

@ -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) {