Add some resource leak protection to new room list badges

Most of the leaks were because we never set `this.rooms` in the notification state, which meant we were constantly triggering the `diff.added` loop.
pull/21833/head
Travis Ralston 2020-06-10 16:04:27 -06:00
parent d3a3b54a82
commit d1c2ecb6cc
2 changed files with 18 additions and 1 deletions

View File

@ -205,7 +205,7 @@ export class RoomNotificationState extends EventEmitter implements IDestroyable
} }
} }
export class ListNotificationState extends EventEmitter { export class ListNotificationState extends EventEmitter implements IDestroyable {
private _count: number; private _count: number;
private _color: NotificationColor; private _color: NotificationColor;
private rooms: Room[] = []; private rooms: Room[] = [];
@ -237,6 +237,7 @@ export class ListNotificationState extends EventEmitter {
const oldRooms = this.rooms; const oldRooms = this.rooms;
const diff = arrayDiff(oldRooms, rooms); const diff = arrayDiff(oldRooms, rooms);
this.rooms = rooms;
for (const oldRoom of diff.removed) { for (const oldRoom of diff.removed) {
const state = this.states[oldRoom.roomId]; const state = this.states[oldRoom.roomId];
delete this.states[oldRoom.roomId]; delete this.states[oldRoom.roomId];
@ -246,12 +247,24 @@ export class ListNotificationState extends EventEmitter {
for (const newRoom of diff.added) { for (const newRoom of diff.added) {
const state = new RoomNotificationState(newRoom); const state = new RoomNotificationState(newRoom);
state.on(NOTIFICATION_STATE_UPDATE, this.onRoomNotificationStateUpdate); state.on(NOTIFICATION_STATE_UPDATE, this.onRoomNotificationStateUpdate);
if (this.states[newRoom.roomId]) {
// "Should never happen" disclaimer.
console.warn("Overwriting notification state for room:", newRoom.roomId);
this.states[newRoom.roomId].destroy();
}
this.states[newRoom.roomId] = state; this.states[newRoom.roomId] = state;
} }
this.calculateTotalState(); this.calculateTotalState();
} }
public destroy() {
for (const state of Object.values(this.states)) {
state.destroy();
}
this.states = {};
}
private onRoomNotificationStateUpdate = () => { private onRoomNotificationStateUpdate = () => {
this.calculateTotalState(); this.calculateTotalState();
}; };

View File

@ -84,6 +84,10 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {
this.state.notificationState.setRooms(this.props.rooms); this.state.notificationState.setRooms(this.props.rooms);
} }
public componentWillUnmount() {
this.state.notificationState.destroy();
}
private onAddRoom = (e) => { private onAddRoom = (e) => {
e.stopPropagation(); e.stopPropagation();
if (this.props.onAddRoom) this.props.onAddRoom(); if (this.props.onAddRoom) this.props.onAddRoom();