sync arch. rooms with Room during init. sync to create summary, timeline

when receiving archived rooms during initial sync, sync them with Room
(e.g. as a joined room) first so the members, timeline get written
and the summary gets created which is then adopted by the ArchivedRoom.
This commit is contained in:
Bruno Windels 2021-05-11 13:02:43 +02:00
parent 2087059c0b
commit e775ed12b4

View file

@ -193,7 +193,7 @@ export class Sync {
const sessionState = new SessionSyncProcessState(); const sessionState = new SessionSyncProcessState();
const inviteStates = this._parseInvites(response.rooms); const inviteStates = this._parseInvites(response.rooms);
const {roomStates, archivedRoomStates} = await this._parseRoomsResponse( const {roomStates, archivedRoomStates} = await this._parseRoomsResponse(
response.rooms, inviteStates, isInitialSync); response.rooms, inviteStates, isInitialSync, log);
try { try {
// take a lock on olm sessions used in this sync so sending a message doesn't change them while syncing // take a lock on olm sessions used in this sync so sending a message doesn't change them while syncing
@ -346,7 +346,7 @@ export class Sync {
]); ]);
} }
async _parseRoomsResponse(roomsSection, inviteStates, isInitialSync) { async _parseRoomsResponse(roomsSection, inviteStates, isInitialSync, log) {
const roomStates = []; const roomStates = [];
const archivedRoomStates = []; const archivedRoomStates = [];
if (roomsSection) { if (roomsSection) {
@ -366,11 +366,11 @@ export class Sync {
if (invite) { if (invite) {
inviteStates.push(new InviteSyncProcessState(invite, false, null, membership)); inviteStates.push(new InviteSyncProcessState(invite, false, null, membership));
} }
const roomState = this._createRoomSyncState(roomId, invite, roomResponse, membership); const roomState = this._createRoomSyncState(roomId, invite, roomResponse, membership, isInitialSync);
if (roomState) { if (roomState) {
roomStates.push(roomState); roomStates.push(roomState);
} }
const ars = await this._createArchivedRoomSyncState(roomId, roomState, roomResponse, membership); const ars = await this._createArchivedRoomSyncState(roomId, roomState, roomResponse, membership, isInitialSync, log);
if (ars) { if (ars) {
archivedRoomStates.push(ars); archivedRoomStates.push(ars);
} }
@ -381,12 +381,17 @@ export class Sync {
return {roomStates, archivedRoomStates}; return {roomStates, archivedRoomStates};
} }
_createRoomSyncState(roomId, invite, roomResponse, membership) { _createRoomSyncState(roomId, invite, roomResponse, membership, isInitialSync) {
let isNewRoom = false; let isNewRoom = false;
let room = this._session.rooms.get(roomId); let room = this._session.rooms.get(roomId);
// create room only on new join, // create room only either on new join,
// don't create a room for a rejected invite // or for an archived room during initial sync,
if (!room && membership === "join") { // where we create the summaryChanges with a joined
// room to then adopt by the archived room.
// This way the limited timeline, members, ...
// we receive also gets written.
// In any case, don't create a room for a rejected invite
if (!room && (membership === "join" || (isInitialSync && membership === "leave"))) {
room = this._session.createRoom(roomId); room = this._session.createRoom(roomId);
isNewRoom = true; isNewRoom = true;
} }
@ -396,10 +401,12 @@ export class Sync {
} }
} }
async _createArchivedRoomSyncState(roomId, roomState, roomResponse, membership) { async _createArchivedRoomSyncState(roomId, roomState, roomResponse, membership, isInitialSync, log) {
let archivedRoom; let archivedRoom;
if (membership === "join") { if (roomState?.shouldAdd && !isInitialSync) {
// when joining, always create the archived room to write the removal // when adding a joined room during incremental sync,
// always create the archived room to write the removal
// of the archived summary
archivedRoom = this._session.createArchivedRoom(roomId); archivedRoom = this._session.createArchivedRoom(roomId);
} else if (membership === "leave") { } else if (membership === "leave") {
if (roomState) { if (roomState) {
@ -411,12 +418,12 @@ export class Sync {
// it from storage first, so we can increment it. // it from storage first, so we can increment it.
// this happens for example when our membership changes // this happens for example when our membership changes
// after leaving (e.g. being (un)banned, possibly after being kicked), etc // after leaving (e.g. being (un)banned, possibly after being kicked), etc
archivedRoom = await this._session.loadArchivedRoom(roomId); archivedRoom = await this._session.loadArchivedRoom(roomId, log);
} }
} }
if (archivedRoom) { if (archivedRoom) {
return new ArchivedRoomSyncProcessState( return new ArchivedRoomSyncProcessState(
archivedRoom, roomState, roomResponse, membership); archivedRoom, roomState, roomResponse, membership);
} }
} }
@ -477,11 +484,11 @@ class RoomSyncProcessState {
} }
get shouldAdd() { get shouldAdd() {
return this.isNewRoom; return this.isNewRoom && this.membership === "join";
} }
get shouldRemove() { get shouldRemove() {
return this.membership !== "join"; return !this.isNewRoom && this.membership !== "join";
} }
get summaryChanges() { get summaryChanges() {
@ -491,11 +498,12 @@ class RoomSyncProcessState {
class ArchivedRoomSyncProcessState { class ArchivedRoomSyncProcessState {
constructor(archivedRoom, roomState, roomResponse, membership) { constructor(archivedRoom, roomState, roomResponse, membership, isInitialSync) {
this.archivedRoom = archivedRoom; this.archivedRoom = archivedRoom;
this.roomState = roomState; this.roomState = roomState;
this.roomResponse = roomResponse; this.roomResponse = roomResponse;
this.membership = membership; this.membership = membership;
this.isInitialSync = isInitialSync;
this.changes = null; this.changes = null;
} }
@ -504,7 +512,7 @@ class ArchivedRoomSyncProcessState {
} }
get shouldAdd() { get shouldAdd() {
return this.roomState && this.membership === "leave"; return (this.roomState || this.isInitialSync) && this.membership === "leave";
} }
get shouldRemove() { get shouldRemove() {