From 43ad3d0c1533a73dec9e479325c328a8db29b518 Mon Sep 17 00:00:00 2001 From: Wesley Aptekar-Cassels Date: Tue, 7 Mar 2023 13:08:58 -0500 Subject: [PATCH] Improve polling algorithm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The existing polling code had a few problems: * It started the timer for a new request when the first request was sent, rather than when a response was received. * It increased the delay regardless of whether the response was a success or a failure. This commit changes it to a more standard exponential backoff system, where it starts with a 5 minute ± 30 second delay, and uses that same delay until it hits an error, at which point the delay is increased by 10%. Once it receives a successful response again, the delay is reset to the default. I suspect this should be nicer on the server, since it avoids the initial sending of many requests. After about half an hour of leaving the page open, the request rate for this new code will be higher than that of the old code, so it's possible that this may cause problems, but I think that a five-minute request frequency should be pretty reasonable. --- bookwyrm/static/js/bookwyrm.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/bookwyrm/static/js/bookwyrm.js b/bookwyrm/static/js/bookwyrm.js index dee4231b8..6a6c0217f 100644 --- a/bookwyrm/static/js/bookwyrm.js +++ b/bookwyrm/static/js/bookwyrm.js @@ -95,7 +95,6 @@ let BookWyrm = new (class { /** * Update a counter with recurring requests to the API - * The delay is slightly randomized and increased on each cycle. * * @param {Object} counter - DOM node * @param {int} delay - frequency for polling in ms @@ -104,16 +103,19 @@ let BookWyrm = new (class { polling(counter, delay) { const bookwyrm = this; - delay = delay || 10000; - delay += Math.random() * 1000; + delay = delay || 5 * 60 * 1000 + (Math.random() - 0.5) * 30 * 1000; setTimeout( function () { fetch("/api/updates/" + counter.dataset.poll) .then((response) => response.json()) - .then((data) => bookwyrm.updateCountElement(counter, data)); - - bookwyrm.polling(counter, delay * 1.25); + .then((data) => { + bookwyrm.updateCountElement(counter, data); + bookwyrm.polling(counter); + }) + .catch(() => { + bookwyrm.polling(counter, delay * 1.1); + }); }, delay, counter