Improve polling algorithm

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.
This commit is contained in:
Wesley Aptekar-Cassels 2023-03-07 13:08:58 -05:00
parent 05a303ea18
commit 43ad3d0c15

View file

@ -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