Sfoglia il codice sorgente

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.
JC Brand 4 anni fa
parent
commit
46f567d0d1

+ 1 - 1
src/headless/core.js

@@ -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();

+ 12 - 11
src/headless/plugins/disco/index.js

@@ -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);
     }
 });

+ 9 - 0
src/headless/plugins/disco/utils.js

@@ -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;
+}