|
var makeTest = require('./context')
|
|
var Bottleneck = require('./bottleneck')
|
|
var assert = require('assert')
|
|
|
|
describe('Batcher', function () {
|
|
var c
|
|
|
|
afterEach(function () {
|
|
return c.limiter.disconnect(false)
|
|
})
|
|
|
|
it('Should batch by time and size', function () {
|
|
c = makeTest()
|
|
var batcher = new Bottleneck.Batcher({
|
|
maxTime: 50,
|
|
maxSize: 3
|
|
})
|
|
var t0 = Date.now()
|
|
var batches = []
|
|
|
|
batcher.on('batch', function (batcher) {
|
|
batches.push(batcher)
|
|
})
|
|
|
|
return Promise.all([
|
|
batcher.add(1).then((x) => c.limiter.schedule(c.promise, null, Date.now() - t0, 1)),
|
|
batcher.add(2).then((x) => c.limiter.schedule(c.promise, null, Date.now() - t0, 2)),
|
|
batcher.add(3).then((x) => c.limiter.schedule(c.promise, null, Date.now() - t0, 3)),
|
|
batcher.add(4).then((x) => c.limiter.schedule(c.promise, null, Date.now() - t0, 4)),
|
|
batcher.add(5).then((x) => c.limiter.schedule(c.promise, null, Date.now() - t0, 5))
|
|
])
|
|
.then(function (data) {
|
|
c.mustEqual(
|
|
data.map((([t, x]) => [Math.floor(t / 50), x])),
|
|
[[0, 1], [0, 2], [0, 3], [1, 4], [1, 5]]
|
|
)
|
|
|
|
return c.last()
|
|
})
|
|
.then(function (results) {
|
|
c.checkDuration(50, 20)
|
|
c.mustEqual(batches, [[1, 2, 3], [4, 5]])
|
|
})
|
|
})
|
|
|
|
it('Should batch by time', function () {
|
|
c = makeTest()
|
|
var batcher = new Bottleneck.Batcher({
|
|
maxTime: 50
|
|
})
|
|
var t0 = Date.now()
|
|
var batches = []
|
|
|
|
batcher.on('batch', function (batcher) {
|
|
batches.push(batcher)
|
|
})
|
|
|
|
return Promise.all([
|
|
batcher.add(1).then((x) => c.limiter.schedule(c.promise, null, Date.now() - t0, 1)),
|
|
batcher.add(2).then((x) => c.limiter.schedule(c.promise, null, Date.now() - t0, 2))
|
|
])
|
|
.then(function (data) {
|
|
c.mustEqual(
|
|
data.map((([t, x]) => [Math.floor(t / 50), x])),
|
|
[[1, 1], [1, 2]]
|
|
)
|
|
|
|
return Promise.all([
|
|
batcher.add(3).then((x) => c.limiter.schedule(c.promise, null, Date.now() - t0, 3)),
|
|
batcher.add(4).then((x) => c.limiter.schedule(c.promise, null, Date.now() - t0, 4))
|
|
])
|
|
})
|
|
.then(function (data) {
|
|
c.mustEqual(
|
|
data.map((([t, x]) => [Math.floor(t / 50), x])),
|
|
[[2, 3], [2, 4]]
|
|
)
|
|
|
|
return c.last()
|
|
})
|
|
.then(function (results) {
|
|
c.checkDuration(100)
|
|
c.mustEqual(batches, [[1, 2], [3, 4]])
|
|
})
|
|
})
|
|
|
|
it('Should batch by size', function () {
|
|
c = makeTest()
|
|
var batcher = new Bottleneck.Batcher({
|
|
maxSize: 2
|
|
})
|
|
var batches = []
|
|
|
|
batcher.on('batch', function (batcher) {
|
|
batches.push(batcher)
|
|
})
|
|
|
|
return Promise.all([
|
|
batcher.add(1).then((x) => c.limiter.schedule(c.promise, null, 1)),
|
|
batcher.add(2).then((x) => c.limiter.schedule(c.promise, null, 2))
|
|
])
|
|
.then(function () {
|
|
return Promise.all([
|
|
batcher.add(3).then((x) => c.limiter.schedule(c.promise, null, 3)),
|
|
batcher.add(4).then((x) => c.limiter.schedule(c.promise, null, 4))
|
|
])
|
|
})
|
|
.then(c.last)
|
|
.then(function (results) {
|
|
c.checkDuration(0)
|
|
c.mustEqual(batches, [[1, 2], [3, 4]])
|
|
})
|
|
})
|
|
|
|
it('Should stagger flushes', function () {
|
|
c = makeTest()
|
|
var batcher = new Bottleneck.Batcher({
|
|
maxTime: 50,
|
|
maxSize: 3
|
|
})
|
|
var t0 = Date.now()
|
|
var batches = []
|
|
|
|
batcher.on('batch', function (batcher) {
|
|
batches.push(batcher)
|
|
})
|
|
|
|
return Promise.all([
|
|
batcher.add(1).then((x) => c.limiter.schedule(c.promise, null, Date.now() - t0, 1)),
|
|
batcher.add(2).then((x) => c.limiter.schedule(c.promise, null, Date.now() - t0, 2))
|
|
])
|
|
.then(function (data) {
|
|
c.mustEqual(
|
|
data.map((([t, x]) => [Math.floor(t / 50), x])),
|
|
[[1, 1], [1, 2]]
|
|
)
|
|
|
|
var promises = []
|
|
promises.push(batcher.add(3).then((x) => c.limiter.schedule(c.promise, null, Date.now() - t0, 3)))
|
|
|
|
return c.wait(10)
|
|
.then(function () {
|
|
promises.push(batcher.add(4).then((x) => c.limiter.schedule(c.promise, null, Date.now() - t0, 4)))
|
|
|
|
return Promise.all(promises)
|
|
})
|
|
})
|
|
.then(function (data) {
|
|
c.mustEqual(
|
|
data.map((([t, x]) => [Math.floor(t / 50), x])),
|
|
[[2, 3], [2, 4]]
|
|
)
|
|
|
|
return c.last()
|
|
})
|
|
.then(function (results) {
|
|
c.checkDuration(120, 20)
|
|
c.mustEqual(batches, [[1, 2], [3, 4]])
|
|
})
|
|
})
|
|
|
|
it('Should force then stagger flushes', function () {
|
|
c = makeTest()
|
|
var batcher = new Bottleneck.Batcher({
|
|
maxTime: 50,
|
|
maxSize: 3
|
|
})
|
|
var t0 = Date.now()
|
|
var batches = []
|
|
|
|
batcher.on('batch', function (batcher) {
|
|
batches.push(batcher)
|
|
})
|
|
|
|
var promises = []
|
|
promises.push(batcher.add(1).then((x) => c.limiter.schedule(c.promise, null, Date.now() - t0, 1)))
|
|
promises.push(batcher.add(2).then((x) => c.limiter.schedule(c.promise, null, Date.now() - t0, 2)))
|
|
|
|
return c.wait(10)
|
|
.then(function () {
|
|
promises.push(batcher.add(3).then((x) => c.limiter.schedule(c.promise, null, Date.now() - t0, 3)))
|
|
|
|
return Promise.all(promises)
|
|
})
|
|
.then(function (data) {
|
|
c.mustEqual(
|
|
data.map((([t, x]) => [Math.floor(t / 50), x])),
|
|
[[0, 1], [0, 2], [0, 3]]
|
|
)
|
|
|
|
return Promise.all([
|
|
batcher.add(4).then((x) => c.limiter.schedule(c.promise, null, Date.now() - t0, 4)),
|
|
batcher.add(5).then((x) => c.limiter.schedule(c.promise, null, Date.now() - t0, 5)),
|
|
])
|
|
})
|
|
.then(function (data) {
|
|
c.mustEqual(
|
|
data.map((([t, x]) => [Math.floor(t / 50), x])),
|
|
[[1, 4], [1, 5]]
|
|
)
|
|
|
|
return c.last()
|
|
})
|
|
.then(function (results) {
|
|
c.checkDuration(85, 25)
|
|
c.mustEqual(batches, [[1, 2, 3], [4, 5]])
|
|
})
|
|
})
|
|
})
|