demarches-normaliennes/app/javascript/shared/remote-poller.js

100 lines
2.4 KiB
JavaScript
Raw Normal View History

import { ajax, delegate } from '@utils';
addEventListener('turbolinks:load', () => {
2020-01-29 12:16:38 +01:00
attachementPoller.deactivate();
exportPoller.deactivate();
2020-01-29 12:16:38 +01:00
const attachments = document.querySelectorAll('[data-attachment-poll-url]');
const exports = document.querySelectorAll('[data-export-poll-url]');
2020-01-29 12:16:38 +01:00
for (let { dataset } of attachments) {
attachementPoller.add(dataset.attachmentPollUrl);
}
for (let { dataset } of exports) {
exportPoller.add(dataset.exportPollUrl);
}
});
addEventListener('attachment:update', ({ detail: { url } }) => {
2020-01-29 12:16:38 +01:00
attachementPoller.add(url);
});
addEventListener('export:update', ({ detail: { url } }) => {
exportPoller.add(url);
});
delegate('click', '[data-attachment-refresh]', event => {
event.preventDefault();
2020-01-29 12:16:38 +01:00
attachementPoller.check();
});
// Periodically check the state of a set of URLs.
//
// Each time the given URL is requested, the matching `show.js.erb` view is rendered,
// causing the state to be refreshed.
//
// This is used mainly to refresh attachments during the anti-virus check,
// but also to refresh the state of a pending spreadsheet export.
2020-01-29 12:16:38 +01:00
class RemotePoller {
urls = new Set();
timeout;
checks = 0;
constructor(settings = {}) {
2020-01-29 12:16:38 +01:00
this.interval = settings.interval;
this.maxChecks = settings.maxChecks;
}
get isEnabled() {
return this.checks <= this.maxChecks;
}
get isActive() {
return this.timeout !== undefined;
}
add(url) {
if (this.isEnabled) {
if (!this.isActive) {
this.activate();
}
this.urls.add(url);
}
}
check() {
let urls = this.urls;
this.reset();
for (let url of urls) {
// Start the request. The JS payload in the response will update the page.
// (Errors are ignored, because background tasks shouldn't report errors to the user.)
ajax({ url, type: 'get' }).catch(() => {});
}
}
activate() {
clearTimeout(this.timeout);
this.timeout = setTimeout(() => {
this.checks++;
2020-01-29 12:16:38 +01:00
this.currentInterval = this.interval * 1.5;
this.check();
2020-01-29 12:16:38 +01:00
}, this.currentInterval);
}
deactivate() {
this.checks = 0;
2020-01-29 12:16:38 +01:00
this.currentInterval = this.interval;
this.reset();
}
reset() {
clearTimeout(this.timeout);
this.urls = new Set();
this.timeout = undefined;
}
}
const attachementPoller = new RemotePoller({ interval: 3000, maxChecks: 5 });
const exportPoller = new RemotePoller({ interval: 6000, maxChecks: 10 });