mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-02-06 11:23:48 -05:00
The `updateContent` module updates a section of the page based on an AJAX request. The current implementation will poll every `x` seconds. If the server takes a long time to respond, this results in a the browser queuing up requests. If a particular endpoint is slow, this can result in one client making enough requests to slow down the whole server, to the point where it gets removed from the loadbalancer, eventually bringing the whole site down. This commit rewrites the module so that it queues up the render operations, not the requests. There is one queue per endpoint, so for `http://example.com/endpoint.json`: 1. Queue is empty ```javascript { 'http://example.com/endpoint.json': [] } ``` 2. Inital re-render is put on the queue… ```javascript { 'http://example.com/endpoint.json': [ function render(){…} ] } ``` …AJAX request fires ``` GET http://example.com/endpoint.json ``` 3. Every `x` seconds, another render operation is put on the queue ```javascript { 'http://example.com/endpoint.json': [ function render(){…}, function render(){…}, function render(){…} ] } ``` 4. AJAX request returns queue is flushed by executing each queued render function in sequence ```javascript render(response); render(response); render(response); ``` ```javascript { 'http://example.com/endpoint.json': [] } ``` 5. Repeat This means that, at most, the AJAX requests will never fire more than once every `x` seconds, where `x` defaults to `1.5`.
45 lines
968 B
JavaScript
45 lines
968 B
JavaScript
(function(Modules) {
|
|
"use strict";
|
|
|
|
var queues = {};
|
|
var dd = new diffDOM();
|
|
|
|
var getRenderer = $component => response => dd.apply(
|
|
$component.get(0),
|
|
dd.diff($component.get(0), $(response[$component.data('key')]).get(0))
|
|
);
|
|
|
|
var getQueue = resource => (
|
|
queues[resource] = queues[resource] || []
|
|
);
|
|
|
|
var flushQueue = function(queue, response) {
|
|
while(queue.length) queue.shift()(response);
|
|
};
|
|
|
|
var poll = function(renderer, resource, queue, interval) {
|
|
|
|
if (queue.push(renderer) === 1) $.get(
|
|
resource,
|
|
response => flushQueue(queue, response)
|
|
);
|
|
|
|
setTimeout(
|
|
() => poll(...arguments), interval
|
|
);
|
|
|
|
};
|
|
|
|
Modules.UpdateContent = function() {
|
|
|
|
this.start = component => poll(
|
|
getRenderer($(component)),
|
|
$(component).data('resource'),
|
|
getQueue($(component).data('resource')),
|
|
($(component).data('interval-seconds') || 1.5) * 1000
|
|
);
|
|
|
|
};
|
|
|
|
})(window.GOVUK.Modules);
|