FIX: Memory Leaks w/ Container (#7750)

approved
#1

FIX: Memory Leaks w/ Container (#7750)

Gives instance initializers the ability to add a teardown method that will be called between tests to clean up after themselves.

diff --git a/app/assets/javascripts/discourse/initializers/csrf-token.js.es6 b/app/assets/javascripts/discourse/initializers/csrf-token.js.es6
index 0ddd5dd..3edee01 100644
--- a/app/assets/javascripts/discourse/initializers/csrf-token.js.es6
+++ b/app/assets/javascripts/discourse/initializers/csrf-token.js.es6
@@ -1,21 +1,28 @@
 //  Append our CSRF token to AJAX requests when necessary.
 
-let installedFilter = false;
+let installed = false;
+let callbacks = $.Callbacks();
 
 export default {
   name: "csrf-token",
-  initialize: function(container) {
+  initialize(container) {
     // Add a CSRF token to all AJAX requests
     let session = container.lookup("session:main");
     session.set("csrfToken", $("meta[name=csrf-token]").attr("content"));
 
-    if (!installedFilter) {
-      $.ajaxPrefilter(function(options, originalOptions, xhr) {
-        if (!options.crossDomain) {
-          xhr.setRequestHeader("X-CSRF-Token", session.get("csrfToken"));
-        }
-      });
-      installedFilter = true;
+    if (!installed) {
+      $.ajaxPrefilter(callbacks.fire);
+      installed = true;
     }
+
+    callbacks.add(function(options, originalOptions, xhr) {
+      if (!options.crossDomain) {
+        xhr.setRequestHeader("X-CSRF-Token", session.get("csrfToken"));
+      }
+    });
+  },
+
+  teardown() {
+    callbacks.empty();
   }
 };
diff --git a/test/javascripts/test_helper.js b/test/javascripts/test_helper.js
index ee3ee12..9d9d859 100644
--- a/test/javascripts/test_helper.js
+++ b/test/javascripts/test_helper.js
@@ -169,6 +169,15 @@ QUnit.testDone(function() {
     });
   });
 
+  Discourse._runInitializer("instanceInitializers", function(
+    name,
+    initializer
+  ) {
+    if (initializer && initializer.teardown) {
+      initializer.teardown();
+    }
+  });
+
   // attempts to remove any subscribed message bus callback
   window.MessageBus.callbacks.forEach(function(callback) {
     window.MessageBus.unsubscribe(callback.channel, callback.func);

GitHub sha: 3d7c26c1

1 Like
Approved #2