Fix memory leak in sessionStorage

The disco entities collection gets recreated and repopulated every time
the connection is re-established or after the user logs in again after
having logged out.

The old disco entities weren't being removed, due to an erroneous
`shouldClearCache` call (not applicable to sessionStorage data).

In addition we need a handler to fire and clear the entities cache when
Converse is going to restart.
This commit is contained in:
JC Brand 2021-06-29 11:20:50 +02:00
parent 18f883545b
commit 46f567d0d1
3 changed files with 22 additions and 12 deletions

View File

@ -928,7 +928,7 @@ _converse.shouldClearCache = () => (
);
export function clearSession () {
export function clearSession () {
_converse.session?.destroy();
delete _converse.session;
_converse.shouldClearCache() && _converse.api.user.settings.clear();

View File

@ -6,7 +6,13 @@
import DiscoEntities from './entities.js';
import DiscoEntity from './entity.js';
import { _converse, api, converse } from '@converse/headless/core.js';
import { initializeDisco, initStreamFeatures, notifyStreamFeaturesAdded, populateStreamFeatures } from './utils.js';
import {
clearSession,
initStreamFeatures,
initializeDisco,
notifyStreamFeaturesAdded,
populateStreamFeatures
} from './utils.js';
import disco_api from './api.js';
const { Strophe } = converse.env;
@ -46,15 +52,10 @@ converse.plugins.add('converse-disco', {
}
});
api.listen.on('clearSession', () => {
if (_converse.shouldClearCache() && _converse.disco_entities) {
Array.from(_converse.disco_entities.models).forEach(e => e.features.clearStore());
Array.from(_converse.disco_entities.models).forEach(e => e.identities.clearStore());
Array.from(_converse.disco_entities.models).forEach(e => e.dataforms.clearStore());
Array.from(_converse.disco_entities.models).forEach(e => e.fields.clearStore());
_converse.disco_entities.clearStore();
delete _converse.disco_entities;
}
});
// All disco entities stored in sessionStorage and are refetched
// upon login or reconnection and then stored with new ids, so to
// avoid sessionStorage filling up, we remove them.
api.listen.on('will-reconnect', clearSession);
api.listen.on('clearSession', clearSession);
}
});

View File

@ -123,3 +123,12 @@ export function populateStreamFeatures () {
});
notifyStreamFeaturesAdded();
}
export function clearSession () {
_converse.disco_entities?.forEach(e => e.features.clearStore());
_converse.disco_entities?.forEach(e => e.identities.clearStore());
_converse.disco_entities?.forEach(e => e.dataforms.clearStore());
_converse.disco_entities?.forEach(e => e.fields.clearStore());
_converse.disco_entities.clearStore();
delete _converse.disco_entities;
}