demarches-normaliennes/app/javascript/shared/remote-poller.js
Pierre de La Morinerie 38c0cdc360 javascript: ignore errors of attachments pooler
Pooling for attachment status is a background operation. Errors should
not be reported to the user, who didn't even ask for this operation to
take place.

This is why we ignore all errors, whether Javascript exceptions or
network errors.
2020-04-07 12:35:54 +02:00

99 lines
2.4 KiB
JavaScript

import { ajax, delegate } from '@utils';
addEventListener('turbolinks:load', () => {
attachementPoller.deactivate();
exportPoller.deactivate();
const attachments = document.querySelectorAll('[data-attachment-poll-url]');
const exports = document.querySelectorAll('[data-export-poll-url]');
for (let { dataset } of attachments) {
attachementPoller.add(dataset.attachmentPollUrl);
}
for (let { dataset } of exports) {
exportPoller.add(dataset.exportPollUrl);
}
});
addEventListener('attachment:update', ({ detail: { url } }) => {
attachementPoller.add(url);
});
addEventListener('export:update', ({ detail: { url } }) => {
exportPoller.add(url);
});
delegate('click', '[data-attachment-refresh]', event => {
event.preventDefault();
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.
class RemotePoller {
urls = new Set();
timeout;
checks = 0;
constructor(settings = {}) {
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++;
this.currentInterval = this.interval * 1.5;
this.check();
}, this.currentInterval);
}
deactivate() {
this.checks = 0;
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 });