38c0cdc360
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.
99 lines
2.4 KiB
JavaScript
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 });
|