From c5174e69824ae366f6691dcb6b8d2d56f225ea68 Mon Sep 17 00:00:00 2001 From: Sam Date: Tue, 1 Jun 2021 12:23:51 +1000 Subject: [PATCH] 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. --- .../discourse/app/initializers/message-bus.js | 14 +++++++++++- .../discourse/app/lib/user-presence.js | 22 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/discourse/app/initializers/message-bus.js b/app/assets/javascripts/discourse/app/initializers/message-bus.js index 13ccf4601bb..2e2df03710c 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 2758338faa9..081fff45534 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