FIX: MessageBus would stall after 20 minutes of inactivity (#13219)

FIX: MessageBus would stall after 20 minutes of inactivity (#13219)

Previous to this change we would switch off MessageBus updating after 20 minutes.

This ensures that when the user becomes present again we turn on long polling.

Without long polling updates can be delayed for minutes.

diff --git a/app/assets/javascripts/discourse/app/initializers/message-bus.js b/app/assets/javascripts/discourse/app/initializers/message-bus.js
index 13ccf46..2e2df03 100644
--- a/app/assets/javascripts/discourse/app/initializers/message-bus.js
+++ b/app/assets/javascripts/discourse/app/initializers/message-bus.js
@@ -2,7 +2,7 @@ import { isProduction, isTesting } from "discourse-common/config/environment";
 // Initialize the message bus to receive messages.
 import getURL from "discourse-common/lib/get-url";
 import { handleLogoff } from "discourse/lib/ajax";
-import userPresent from "discourse/lib/user-presence";
+import userPresent, { onPresenceChange } from "discourse/lib/user-presence";
 
 const LONG_POLL_AFTER_UNSEEN_TIME = 1200000; // 20 minutes
 const CONNECTIVITY_ERROR_CLASS = "message-bus-offline";
@@ -51,6 +51,18 @@ export default {
     // we do not want to start anything till document is complete
     messageBus.stop();
 
+    // This will notify MessageBus to force a long poll after user becomes
+    // present
+    // When 20 minutes pass we stop long polling due to "shouldLongPollCallback".
+    onPresenceChange({
+      unseenTime: LONG_POLL_AFTER_UNSEEN_TIME,
+      callback: () => {
+        if (messageBus.onVisibilityChange) {
+          messageBus.onVisibilityChange();
+        }
+      },
+    });
+
     if (siteSettings.login_required && !user) {
       // Endpoint is not available in this case, so don't try
       return;
diff --git a/app/assets/javascripts/discourse/app/lib/user-presence.js b/app/assets/javascripts/discourse/app/lib/user-presence.js
index 2758338..081fff4 100644
--- a/app/assets/javascripts/discourse/app/lib/user-presence.js
+++ b/app/assets/javascripts/discourse/app/lib/user-presence.js
@@ -25,8 +25,30 @@ export default function (maxUnseenTime) {
   }
 }
 
+const callbacks = [];
+
+const MIN_DELTA = 60000;
+
 export function seenUser() {
+  let lastSeenTime = seenUserTime;
   seenUserTime = Date.now();
+  let delta = seenUserTime - lastSeenTime;
+
+  if (lastSeenTime && delta > MIN_DELTA) {
+    callbacks.forEach((info) => {
+      if (delta > info.unseenTime) {
+        info.callback();
+      }
+    });
+  }
+}
+
+// register a callback for cases where presence changed
+export function onPresenceChange(maxUnseenTime, callback) {
+  if (maxUnseenTime < MIN_DELTA) {
+    throw "unseenTime is too short";
+  }
+  callbacks.push({ unseenTime: maxUnseenTime, callback: callback });
 }
 
 // We could piggieback on the Scroll mixin, but it is not applied

GitHub sha: c5174e69

1 Like

This commit appears in #13219 which was approved by tgxworld. It was merged by SamSaffron.