Add locking to avoid index corruption
When a new room is added there's a fairly good chance that the other events being dispatched will happen in the middle of (for example) the room list being re-sorted. This commit wraps the entire handleRoomUpdate() function for the underlying algorithms in a lock so that if we're unlucky enough to get an update while we're sorting (as the ImportanceAlgorithm splices out what it is sorting) we won't scream about invalid index errors.pull/21833/head
parent
c7a83e65f0
commit
223ee0dbdb
|
@ -179,6 +179,9 @@ export class ImportanceAlgorithm extends OrderingAlgorithm {
|
|||
}
|
||||
|
||||
public async handleRoomUpdate(room: Room, cause: RoomUpdateCause): Promise<boolean> {
|
||||
try {
|
||||
await this.updateLock.acquireAsync();
|
||||
|
||||
if (cause === RoomUpdateCause.NewRoom || cause === RoomUpdateCause.RoomRemoved) {
|
||||
return this.handleSplice(room, cause);
|
||||
}
|
||||
|
@ -218,6 +221,9 @@ export class ImportanceAlgorithm extends OrderingAlgorithm {
|
|||
await this.sortCategory(category);
|
||||
|
||||
return true; // change made
|
||||
} finally {
|
||||
await this.updateLock.release();
|
||||
}
|
||||
}
|
||||
|
||||
private async sortCategory(category: Category) {
|
||||
|
|
|
@ -38,6 +38,9 @@ export class NaturalAlgorithm extends OrderingAlgorithm {
|
|||
}
|
||||
|
||||
public async handleRoomUpdate(room, cause): Promise<boolean> {
|
||||
try {
|
||||
await this.updateLock.acquireAsync();
|
||||
|
||||
const isSplice = cause === RoomUpdateCause.NewRoom || cause === RoomUpdateCause.RoomRemoved;
|
||||
const isInPlace = cause === RoomUpdateCause.Timeline || cause === RoomUpdateCause.ReadReceipt;
|
||||
if (!isSplice && !isInPlace) {
|
||||
|
@ -56,5 +59,8 @@ export class NaturalAlgorithm extends OrderingAlgorithm {
|
|||
this.cachedOrderedRooms = await sortRoomsWithAlgorithm(this.cachedOrderedRooms, this.tagId, this.sortingAlgorithm);
|
||||
|
||||
return true;
|
||||
} finally {
|
||||
await this.updateLock.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
import { Room } from "matrix-js-sdk/src/models/room";
|
||||
import { RoomUpdateCause, TagID } from "../../models";
|
||||
import { SortAlgorithm } from "../models";
|
||||
import AwaitLock from "await-lock";
|
||||
|
||||
/**
|
||||
* Represents a list ordering algorithm. Subclasses should populate the
|
||||
|
@ -25,6 +26,7 @@ import { SortAlgorithm } from "../models";
|
|||
export abstract class OrderingAlgorithm {
|
||||
protected cachedOrderedRooms: Room[];
|
||||
protected sortingAlgorithm: SortAlgorithm;
|
||||
protected readonly updateLock = new AwaitLock();
|
||||
|
||||
protected constructor(protected tagId: TagID, initialSortingAlgorithm: SortAlgorithm) {
|
||||
// noinspection JSIgnoredPromiseFromCall
|
||||
|
|
Loading…
Reference in New Issue