Skip to content

Commit ee90bd6

Browse files
authored
longPolling: false option (#5154)
* longPolling: false option * please the eslint god
1 parent e91f2dd commit ee90bd6

3 files changed

Lines changed: 31 additions & 7 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
* Translation strings added for the layout- and layout-column-widgets.
88
* When switching locale from the doc editor, ask if the user wants to localize the current document in the target locale or want to start a blank document.
9+
* Introduced a new `longPolling: false` option for the `@apostrophecms/notification` module. This eliminates long-pending requests when logged in, but also slows down the delivery of notifications. The behavior can be tuned further via the `pollingInterval` option, which defaults to `5000` milliseconds.
910

1011
### Changes
1112

modules/@apostrophecms/notification/index.js

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44
//
55
// ## Options
66
//
7+
// ### `longPolling`: by default, to provide a swift response, ApostropheCMS
8+
// keeps a request for new notifications alive until the long polling
9+
// timeout expires (see below). However, `longPolling: false` can be used
10+
// to give an immediate response, in which case the front end will poll
11+
// the old-fashioned way, respecting the `pollingInterval`.
12+
//
713
// ### `queryInterval`: interval in milliseconds between MongoDB
814
// queries while long polling for notifications. Defaults to 500
915
// (1/2 second). Set it longer if you prefer fewer queries, however
@@ -15,12 +21,22 @@
1521
// Defaults to 10000 (10 seconds) to avoid typical proxy server timeouts.
1622
// Until it times out the request will keep making MongoDB queries to
1723
// see if any new notifications are available (long polling).
24+
//
25+
// ### `pollingInterval`: when `longPolling` is set to `false`, this
26+
// option determines how often the browser polls for new notifications.
27+
// Not used when `longPolling` is `true` (the default).
28+
// `pollingInterval` defaults to 5000 (5 seconds).
1829

1930
const delay = require('bluebird').delay;
2031

2132
module.exports = {
2233
options: {
23-
alias: 'notification'
34+
alias: 'notification',
35+
longPolling: true,
36+
longPollingTimeout: 10000,
37+
queryInterval: 1000,
38+
// Used only when longPolling is false
39+
pollingInterval: 5000
2440
},
2541
extend: '@apostrophecms/module',
2642
async init(self) {
@@ -64,7 +80,10 @@ module.exports = {
6480
return await attempt();
6581

6682
async function attempt() {
67-
if (Date.now() - start >= (self.options.longPollingTimeout || 10000)) {
83+
if (
84+
self.options.longPolling &&
85+
(Date.now() - start >= self.options.longPollingTimeout)
86+
) {
6887
return {
6988
notifications: [],
7089
dismissed: []
@@ -75,11 +94,10 @@ module.exports = {
7594
modifiedOnOrSince,
7695
seenIds
7796
});
78-
if (!notifications.length && !dismissed.length) {
97+
if (self.options.longPolling && !notifications.length && !dismissed.length) {
7998
await delay(self.options.queryInterval || 1000);
8099
return attempt();
81100
}
82-
83101
return {
84102
notifications,
85103
dismissed
@@ -208,7 +226,9 @@ module.exports = {
208226
return {
209227
getBrowserData(req) {
210228
return {
211-
action: self.action
229+
action: self.action,
230+
longPolling: self.options.longPolling,
231+
pollingInterval: self.options.pollingInterval
212232
};
213233
},
214234
// When used server-side, call with `req` as the first argument,

modules/@apostrophecms/ui/ui/apos/stores/notification.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,13 @@ export const useNotificationStore = defineStore('notification', () => {
107107
return !res.dismissed.some((element) => notif._id === element._id);
108108
});
109109
}
110-
// Long polling, we should reconnect promptly, the server
110+
// If using long polling we should reconnect promptly, the server
111111
// is responsible for keeping that request open for a reasonable
112112
// amount of time if there are no new messages, not us
113-
setTimeout(poll, 50);
113+
const timeout = apos.notification.longPolling
114+
? 50
115+
: apos.notification.pollingInterval;
116+
setTimeout(poll, timeout);
114117
}
115118
} catch (err) {
116119
// eslint-disable-next-line no-console

0 commit comments

Comments
 (0)