handle overlap with existing timeline when rejoining room
This commit is contained in:
parent
ff4abbc5ba
commit
ec0de15da6
2 changed files with 31 additions and 3 deletions
|
@ -248,8 +248,9 @@ export class Room extends EventEmitter {
|
||||||
/** @package */
|
/** @package */
|
||||||
async writeSync(roomResponse, isInitialSync, {summaryChanges, decryptChanges, roomEncryption, retryEntries}, txn, log) {
|
async writeSync(roomResponse, isInitialSync, {summaryChanges, decryptChanges, roomEncryption, retryEntries}, txn, log) {
|
||||||
log.set("id", this.id);
|
log.set("id", this.id);
|
||||||
|
const isRejoin = summaryChanges.membership === "join" && this._summary.data.membership === "leave";
|
||||||
const {entries: newEntries, newLiveKey, memberChanges} =
|
const {entries: newEntries, newLiveKey, memberChanges} =
|
||||||
await log.wrap("syncWriter", log => this._syncWriter.writeSync(roomResponse, txn, log), log.level.Detail);
|
await log.wrap("syncWriter", log => this._syncWriter.writeSync(roomResponse, isRejoin, txn, log), log.level.Detail);
|
||||||
let allEntries = newEntries;
|
let allEntries = newEntries;
|
||||||
if (decryptChanges) {
|
if (decryptChanges) {
|
||||||
const decryption = await log.wrap("decryptChanges", log => decryptChanges.write(txn, log));
|
const decryption = await log.wrap("decryptChanges", log => decryptChanges.write(txn, log));
|
||||||
|
|
|
@ -190,6 +190,26 @@ export class SyncWriter {
|
||||||
return currentKey;
|
return currentKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _handleRejoinOverlap(timeline, txn, log) {
|
||||||
|
if (this._lastLiveKey) {
|
||||||
|
const {fragmentId} = this._lastLiveKey;
|
||||||
|
const [lastEvent] = await txn.timelineEvents.lastEvents(this._roomId, fragmentId, 1);
|
||||||
|
if (lastEvent) {
|
||||||
|
const lastEventId = lastEvent.event.event_id;
|
||||||
|
const {events} = timeline;
|
||||||
|
const index = events.findIndex(event => event.event_id === lastEventId);
|
||||||
|
if (index !== -1) {
|
||||||
|
log.set("overlap_event_id", lastEventId);
|
||||||
|
return {
|
||||||
|
limited: false,
|
||||||
|
events: events.slice(index + 1)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return timeline;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {SyncWriterResult}
|
* @type {SyncWriterResult}
|
||||||
* @property {Array<BaseEntry>} entries new timeline entries written
|
* @property {Array<BaseEntry>} entries new timeline entries written
|
||||||
|
@ -197,12 +217,19 @@ export class SyncWriter {
|
||||||
* @property {Map<string, MemberChange>} memberChanges member changes in the processed sync ny user id
|
* @property {Map<string, MemberChange>} memberChanges member changes in the processed sync ny user id
|
||||||
*
|
*
|
||||||
* @param {Object} roomResponse [description]
|
* @param {Object} roomResponse [description]
|
||||||
|
* @param {boolean} isRejoin whether the room was rejoined in the sync being processed
|
||||||
* @param {Transaction} txn
|
* @param {Transaction} txn
|
||||||
* @return {SyncWriterResult}
|
* @return {SyncWriterResult}
|
||||||
*/
|
*/
|
||||||
async writeSync(roomResponse, txn, log) {
|
async writeSync(roomResponse, isRejoin, txn, log) {
|
||||||
const entries = [];
|
const entries = [];
|
||||||
const {timeline} = roomResponse;
|
let {timeline} = roomResponse;
|
||||||
|
// we have rejoined the room after having synced it before,
|
||||||
|
// check for overlap with the last synced event
|
||||||
|
log.set("isRejoin", isRejoin);
|
||||||
|
if (isRejoin) {
|
||||||
|
timeline = await this._handleRejoinOverlap(timeline, txn, log);
|
||||||
|
}
|
||||||
const memberChanges = new Map();
|
const memberChanges = new Map();
|
||||||
// important this happens before _writeTimeline so
|
// important this happens before _writeTimeline so
|
||||||
// members are available in the transaction
|
// members are available in the transaction
|
||||||
|
|
Reference in a new issue