Fix various leaks due to method re-binding

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
Michael Telatynski 2020-02-20 02:35:30 +00:00
parent 12eb408c58
commit 16bbea0b59
7 changed files with 31 additions and 29 deletions

View file

@ -153,10 +153,12 @@ const Notifier = {
}, },
start: function() { start: function() {
this.boundOnEvent = this.onEvent.bind(this); // do not re-bind in the case of repeated call
this.boundOnSyncStateChange = this.onSyncStateChange.bind(this); this.boundOnEvent = this.boundOnEvent || this.onEvent.bind(this);
this.boundOnRoomReceipt = this.onRoomReceipt.bind(this); this.boundOnSyncStateChange = this.boundOnSyncStateChange || this.onSyncStateChange.bind(this);
this.boundOnEventDecrypted = this.onEventDecrypted.bind(this); this.boundOnRoomReceipt = this.boundOnRoomReceipt || this.onRoomReceipt.bind(this);
this.boundOnEventDecrypted = this.boundOnEventDecrypted || this.onEventDecrypted.bind(this);
MatrixClientPeg.get().on('event', this.boundOnEvent); MatrixClientPeg.get().on('event', this.boundOnEvent);
MatrixClientPeg.get().on('Room.receipt', this.boundOnRoomReceipt); MatrixClientPeg.get().on('Room.receipt', this.boundOnRoomReceipt);
MatrixClientPeg.get().on('Event.decrypted', this.boundOnEventDecrypted); MatrixClientPeg.get().on('Event.decrypted', this.boundOnEventDecrypted);
@ -166,7 +168,7 @@ const Notifier = {
}, },
stop: function() { stop: function() {
if (MatrixClientPeg.get() && this.boundOnRoomTimeline) { if (MatrixClientPeg.get()) {
MatrixClientPeg.get().removeListener('Event', this.boundOnEvent); MatrixClientPeg.get().removeListener('Event', this.boundOnEvent);
MatrixClientPeg.get().removeListener('Room.receipt', this.boundOnRoomReceipt); MatrixClientPeg.get().removeListener('Room.receipt', this.boundOnRoomReceipt);
MatrixClientPeg.get().removeListener('Event.decrypted', this.boundOnEventDecrypted); MatrixClientPeg.get().removeListener('Event.decrypted', this.boundOnEventDecrypted);

View file

@ -46,7 +46,7 @@ export default class ManageEventIndexDialog extends React.Component {
}; };
} }
async updateCurrentRoom(room) { updateCurrentRoom = async (room) => {
const eventIndex = EventIndexPeg.get(); const eventIndex = EventIndexPeg.get();
const stats = await eventIndex.getStats(); const stats = await eventIndex.getStats();
let currentRoom = null; let currentRoom = null;
@ -63,13 +63,13 @@ export default class ManageEventIndexDialog extends React.Component {
roomCount: roomCount, roomCount: roomCount,
currentRoom: currentRoom, currentRoom: currentRoom,
}); });
} };
componentWillUnmount(): void { componentWillUnmount(): void {
const eventIndex = EventIndexPeg.get(); const eventIndex = EventIndexPeg.get();
if (eventIndex !== null) { if (eventIndex !== null) {
eventIndex.removeListener("changedCheckpoint", this.updateCurrentRoom.bind(this)); eventIndex.removeListener("changedCheckpoint", this.updateCurrentRoom);
} }
} }
@ -83,7 +83,7 @@ export default class ManageEventIndexDialog extends React.Component {
const eventIndex = EventIndexPeg.get(); const eventIndex = EventIndexPeg.get();
if (eventIndex !== null) { if (eventIndex !== null) {
eventIndex.on("changedCheckpoint", this.updateCurrentRoom.bind(this)); eventIndex.on("changedCheckpoint", this.updateCurrentRoom);
const stats = await eventIndex.getStats(); const stats = await eventIndex.getStats();
const roomStats = eventIndex.crawlingRooms(); const roomStats = eventIndex.crawlingRooms();

View file

@ -95,8 +95,8 @@ const FilePanel = createReactClass({
// this could be made more general in the future or the filter logic // this could be made more general in the future or the filter logic
// could be fixed. // could be fixed.
if (EventIndexPeg.get() !== null) { if (EventIndexPeg.get() !== null) {
client.on('Room.timeline', this.onRoomTimeline.bind(this)); client.on('Room.timeline', this.onRoomTimeline);
client.on('Event.decrypted', this.onEventDecrypted.bind(this)); client.on('Event.decrypted', this.onEventDecrypted);
} }
}, },
@ -107,8 +107,8 @@ const FilePanel = createReactClass({
if (!MatrixClientPeg.get().isRoomEncrypted(this.props.roomId)) return; if (!MatrixClientPeg.get().isRoomEncrypted(this.props.roomId)) return;
if (EventIndexPeg.get() !== null) { if (EventIndexPeg.get() !== null) {
client.removeListener('Room.timeline', this.onRoomTimeline.bind(this)); client.removeListener('Room.timeline', this.onRoomTimeline);
client.removeListener('Event.decrypted', this.onEventDecrypted.bind(this)); client.removeListener('Event.decrypted', this.onEventDecrypted);
} }
}, },

View file

@ -37,7 +37,7 @@ export default class EventIndexPanel extends React.Component {
}; };
} }
async updateCurrentRoom(room) { updateCurrentRoom = async (room) => {
const eventIndex = EventIndexPeg.get(); const eventIndex = EventIndexPeg.get();
const stats = await eventIndex.getStats(); const stats = await eventIndex.getStats();
@ -45,13 +45,13 @@ export default class EventIndexPanel extends React.Component {
eventIndexSize: stats.size, eventIndexSize: stats.size,
roomCount: stats.roomCount, roomCount: stats.roomCount,
}); });
} };
componentWillUnmount(): void { componentWillUnmount(): void {
const eventIndex = EventIndexPeg.get(); const eventIndex = EventIndexPeg.get();
if (eventIndex !== null) { if (eventIndex !== null) {
eventIndex.removeListener("changedCheckpoint", this.updateCurrentRoom.bind(this)); eventIndex.removeListener("changedCheckpoint", this.updateCurrentRoom);
} }
} }
@ -68,7 +68,7 @@ export default class EventIndexPanel extends React.Component {
let roomCount = 0; let roomCount = 0;
if (eventIndex !== null) { if (eventIndex !== null) {
eventIndex.on("changedCheckpoint", this.updateCurrentRoom.bind(this)); eventIndex.on("changedCheckpoint", this.updateCurrentRoom);
const stats = await eventIndex.getStats(); const stats = await eventIndex.getStats();
eventIndexSize = stats.size; eventIndexSize = stats.size;

View file

@ -107,20 +107,20 @@ export default class RolesRoomSettingsTab extends React.Component {
}; };
componentDidMount(): void { componentDidMount(): void {
MatrixClientPeg.get().on("RoomState.members", this._onRoomMembership.bind(this)); MatrixClientPeg.get().on("RoomState.members", this._onRoomMembership);
} }
componentWillUnmount(): void { componentWillUnmount(): void {
const client = MatrixClientPeg.get(); const client = MatrixClientPeg.get();
if (client) { if (client) {
client.removeListener("RoomState.members", this._onRoomMembership.bind(this)); client.removeListener("RoomState.members", this._onRoomMembership);
} }
} }
_onRoomMembership(event, state, member) { _onRoomMembership = (event, state, member) => {
if (state.roomId !== this.props.roomId) return; if (state.roomId !== this.props.roomId) return;
this.forceUpdate(); this.forceUpdate();
} };
_populateDefaultPlEvents(eventsSection, stateLevel, eventsLevel) { _populateDefaultPlEvents(eventsSection, stateLevel, eventsLevel) {
for (const desiredEvent of Object.keys(plEventsToShow)) { for (const desiredEvent of Object.keys(plEventsToShow)) {

View file

@ -54,14 +54,14 @@ export class IntegrationManagers {
startWatching(): void { startWatching(): void {
this.stopWatching(); this.stopWatching();
this._client = MatrixClientPeg.get(); this._client = MatrixClientPeg.get();
this._client.on("accountData", this._onAccountData.bind(this)); this._client.on("accountData", this._onAccountData);
this._compileManagers(); this._compileManagers();
setInterval(() => this._setupHomeserverManagers(), HS_MANAGERS_REFRESH_INTERVAL); setInterval(() => this._setupHomeserverManagers(), HS_MANAGERS_REFRESH_INTERVAL);
} }
stopWatching(): void { stopWatching(): void {
if (!this._client) return; if (!this._client) return;
this._client.removeListener("accountData", this._onAccountData.bind(this)); this._client.removeListener("accountData", this._onAccountData);
if (this._wellknownRefreshTimerId !== null) clearInterval(this._wellknownRefreshTimerId); if (this._wellknownRefreshTimerId !== null) clearInterval(this._wellknownRefreshTimerId);
} }
@ -136,11 +136,11 @@ export class IntegrationManagers {
this._primaryManager = null; // reset primary this._primaryManager = null; // reset primary
} }
_onAccountData(ev: MatrixEvent): void { _onAccountData = (ev: MatrixEvent): void => {
if (ev.getType() === 'm.widgets') { if (ev.getType() === 'm.widgets') {
this._compileManagers(); this._compileManagers();
} }
} };
hasManager(): boolean { hasManager(): boolean {
return this._managers.length > 0; return this._managers.length > 0;

View file

@ -61,7 +61,7 @@ export class Mjolnir {
setup() { setup() {
if (!MatrixClientPeg.get()) return; if (!MatrixClientPeg.get()) return;
this._updateLists(SettingsStore.getValue("mjolnirRooms")); this._updateLists(SettingsStore.getValue("mjolnirRooms"));
MatrixClientPeg.get().on("RoomState.events", this._onEvent.bind(this)); MatrixClientPeg.get().on("RoomState.events", this._onEvent);
} }
stop() { stop() {
@ -76,7 +76,7 @@ export class Mjolnir {
} }
if (!MatrixClientPeg.get()) return; if (!MatrixClientPeg.get()) return;
MatrixClientPeg.get().removeListener("RoomState.events", this._onEvent.bind(this)); MatrixClientPeg.get().removeListener("RoomState.events", this._onEvent);
} }
async getOrCreatePersonalList(): Promise<BanList> { async getOrCreatePersonalList(): Promise<BanList> {
@ -130,13 +130,13 @@ export class Mjolnir {
this._lists = this._lists.filter(b => b.roomId !== roomId); this._lists = this._lists.filter(b => b.roomId !== roomId);
} }
_onEvent(event) { _onEvent = (event) => {
if (!MatrixClientPeg.get()) return; if (!MatrixClientPeg.get()) return;
if (!this._roomIds.includes(event.getRoomId())) return; if (!this._roomIds.includes(event.getRoomId())) return;
if (!ALL_RULE_TYPES.includes(event.getType())) return; if (!ALL_RULE_TYPES.includes(event.getType())) return;
this._updateLists(this._roomIds); this._updateLists(this._roomIds);
} };
_onListsChanged(settingName, roomId, atLevel, newValue) { _onListsChanged(settingName, roomId, atLevel, newValue) {
// We know that ban lists are only recorded at one level so we don't need to re-eval them // We know that ban lists are only recorded at one level so we don't need to re-eval them