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.
This commit is contained in:
parent
c7a83e65f0
commit
223ee0dbdb
3 changed files with 69 additions and 55 deletions
|
@ -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…
Add table
Add a link
Reference in a new issue