mirror of
https://github.com/weaveworks/scope.git
synced 2026-03-03 02:00:43 +00:00
116 lines
3.2 KiB
JavaScript
116 lines
3.2 KiB
JavaScript
import _ from 'lodash';
|
|
import debug from 'debug';
|
|
import Immutable from 'immutable';
|
|
|
|
import { receiveNodesDelta } from '../actions/app-actions';
|
|
import AppStore from '../stores/app-store';
|
|
|
|
const log = debug('scope:update-buffer-utils');
|
|
const makeList = Immutable.List;
|
|
const feedInterval = 1000;
|
|
const bufferLength = 100;
|
|
|
|
let deltaBuffer = makeList();
|
|
let updateTimer = null;
|
|
|
|
function isPaused() {
|
|
return AppStore.isUpdatePaused();
|
|
}
|
|
|
|
export function resetUpdateBuffer() {
|
|
clearTimeout(updateTimer);
|
|
deltaBuffer = deltaBuffer.clear();
|
|
}
|
|
|
|
function maybeUpdate() {
|
|
if (isPaused()) {
|
|
clearTimeout(updateTimer);
|
|
resetUpdateBuffer();
|
|
} else {
|
|
if (deltaBuffer.size > 0) {
|
|
const delta = deltaBuffer.first();
|
|
deltaBuffer = deltaBuffer.shift();
|
|
receiveNodesDelta(delta);
|
|
}
|
|
if (deltaBuffer.size > 0) {
|
|
updateTimer = setTimeout(maybeUpdate, feedInterval);
|
|
}
|
|
}
|
|
}
|
|
|
|
// consolidate first buffer entry with second
|
|
function consolidateBuffer() {
|
|
const first = deltaBuffer.first();
|
|
deltaBuffer = deltaBuffer.shift();
|
|
const second = deltaBuffer.first();
|
|
let toAdd = _.union(first.add, second.add);
|
|
let toUpdate = _.union(first.update, second.update);
|
|
let toRemove = _.union(first.remove, second.remove);
|
|
log('Consolidating delta buffer', 'add', _.size(toAdd), 'update',
|
|
_.size(toUpdate), 'remove', _.size(toRemove));
|
|
|
|
// check if an added node in first was updated in second -> add second update
|
|
toAdd = _.map(toAdd, node => {
|
|
const updateNode = _.find(second.update, {id: node.id});
|
|
if (updateNode) {
|
|
toUpdate = _.reject(toUpdate, {id: node.id});
|
|
return updateNode;
|
|
}
|
|
return node;
|
|
});
|
|
|
|
// check if an updated node in first was updated in second -> updated second update
|
|
// no action needed, successive updates are fine
|
|
|
|
// check if an added node in first was removed in second -> dont add, dont remove
|
|
_.each(first.add, node => {
|
|
const removedNode = _.find(second.remove, {id: node.id});
|
|
if (removedNode) {
|
|
toAdd = _.reject(toAdd, {id: node.id});
|
|
toRemove = _.reject(toRemove, {id: node.id});
|
|
}
|
|
});
|
|
|
|
// check if an updated node in first was removed in second -> remove
|
|
_.each(first.update, node => {
|
|
const removedNode = _.find(second.remove, {id: node.id});
|
|
if (removedNode) {
|
|
toUpdate = _.reject(toUpdate, {id: node.id});
|
|
}
|
|
});
|
|
|
|
// check if an removed node in first was added in second -> update
|
|
// remove -> add is fine for the store
|
|
|
|
// update buffer
|
|
log('Consolidated delta buffer', 'add', _.size(toAdd), 'update',
|
|
_.size(toUpdate), 'remove', _.size(toRemove));
|
|
deltaBuffer.set(0, {
|
|
add: toAdd.length > 0 ? toAdd : null,
|
|
update: toUpdate.length > 0 ? toUpdate : null,
|
|
remove: toRemove.length > 0 ? toRemove : null
|
|
});
|
|
}
|
|
|
|
export function bufferDeltaUpdate(delta) {
|
|
if (delta.add === null && delta.update === null && delta.remove === null) {
|
|
log('Discarding empty nodes delta');
|
|
return;
|
|
}
|
|
|
|
if (deltaBuffer.size >= bufferLength) {
|
|
consolidateBuffer();
|
|
}
|
|
|
|
deltaBuffer = deltaBuffer.push(delta);
|
|
log('Buffering node delta, new size', deltaBuffer.size);
|
|
}
|
|
|
|
export function getUpdateBufferSize() {
|
|
return deltaBuffer.size;
|
|
}
|
|
|
|
export function resumeUpdate() {
|
|
maybeUpdate();
|
|
}
|