Skip to content

Commit

Permalink
batchedAdd no longer leaking timers
Browse files Browse the repository at this point in the history
  • Loading branch information
prawnsalad committed May 15, 2020
1 parent d64ba6e commit b628d1f
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 45 deletions.
34 changes: 18 additions & 16 deletions src/libs/batchedAdd.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
export default function batchedAdd(singleFn, batchedFn, numInsertsSec = 3) {
let queue = [];
let numInLastSec = 0;
let isLooping = false;
let queueLoopTmr = null;
let loopInterval = 1000;
let checkSecRateTmr = null;

function queueLoop() {
numInLastSec = 0;
Expand All @@ -18,35 +19,36 @@ export default function batchedAdd(singleFn, batchedFn, numInsertsSec = 3) {
let q = queue;
queue = [];
batchedFn(q);
numInLastSec = 0;
setTimeout(queueLoop, loopInterval);
queueLoopTmr = setTimeout(queueLoop, loopInterval);
} else {
isLooping = false;
queueLoopTmr = null;
}
}

function maybeStartLoop() {
if (isLooping) {
return;
if (!queueLoopTmr) {
queueLoopTmr = setTimeout(queueLoop, loopInterval);
}

isLooping = true;
setTimeout(queueLoop, loopInterval);
}

function resetAddCounter(doResetNum) {
if (doResetNum) {
numInLastSec = 0;
}
if (!isLooping) {
setTimeout(resetAddCounter, 1000, true);
// Reset numInLastSec after loopInterval. This allows enough time for the counter to
// increase to detect batching. Only needs to run if we are not currently batching and
// only needs to run once at a time.
function resetAddCounter() {
if (!queueLoopTmr && !checkSecRateTmr) {
checkSecRateTmr = setTimeout(() => {
checkSecRateTmr = null;
if (!queueLoopTmr) {
numInLastSec = 0;
}
}, loopInterval);
}
}

function batchFn(item) {
numInLastSec++;

// Under 1 second, queue them
// If already queuing or we reached our limit on items/sec, queue the item
if (queue.length || numInLastSec > numInsertsSec) {
queue.push(item);
maybeStartLoop();
Expand Down
2 changes: 1 addition & 1 deletion src/libs/state/BufferState.js
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ function createMessageBatch(bufferState) {
}
};

return batchedAdd(addSingleMessage, addMultipleMessages, 2);
return batchedAdd(addSingleMessage, addMultipleMessages, 4);
}

// Update our user list status every 30seconds to get each users current away status
Expand Down
59 changes: 31 additions & 28 deletions tests/unit/BatchAdd.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ describe('batchedAdd.vue', () => {
};

let batch = batchedAdd(singleItem, batchItems);
batch('item');
batch('item');
batch('item');
batch('item1');
batch('item2');
batch('item3');
});

it('should process a batched item after three single items', (done) => {
Expand All @@ -37,36 +37,39 @@ describe('batchedAdd.vue', () => {
};
let batchItems = () => {
if (singleCount !== 3) {
done(new Error('Expected 3 single items before a batch'));
done(new Error('Expected 3 single items before a batch, found ' + singleCount));
} else {
done();
}
};

let batch = batchedAdd(singleItem, batchItems);
batch('item');
batch('item');
batch('item');
batch('item');
batch('item1');
batch('item2');
batch('item3');
batch('item4');
});

it('should process 3 items in a batch', (done) => {
let singleItem = () => {};
let singleItem = (item) => {
console.log('singleItem:', item);
};
let batchItems = (items) => {
console.log('batchItems:', items);
if (items.length !== 3) {
done(new Error('Expected 3 items in a batch'));
done(new Error(`Expected 3 items in a batch, found ${items.length}`));
} else {
done();
}
};

let batch = batchedAdd(singleItem, batchItems);
batch('item');
batch('item');
batch('item');
batch('item');
batch('item');
batch('item');
batch('item1');
batch('item2');
batch('item3');
batch('item4');
batch('item5');
batch('item6');
});

it('should process a single item after a batch has finished', (done) => {
Expand All @@ -86,16 +89,16 @@ describe('batchedAdd.vue', () => {
};

let batch = batchedAdd(singleItem, batchItems);
batch('item');
batch('item');
batch('item');
// Batch kicks in ehre
batch('item');
batch('item');
batch('item');
batch('item1');
batch('item2');
batch('item3');
// Batch kicks in here
batch('item4');
batch('item5');
batch('item6');
setTimeout(() => {
// Should revert back to being a single item
batch('item');
batch('item7');
}, 1200);
});

Expand All @@ -112,11 +115,11 @@ describe('batchedAdd.vue', () => {
};

let batch = batchedAdd(singleItem, batchItems);
batch('item');
batch('item');
batch('item');
batch('item1');
batch('item2');
batch('item3');
setTimeout(() => {
batch('item');
batch('item4');
}, 1200);
}, 3000);
});

0 comments on commit b628d1f

Please sign in to comment.