[kbn-build] Extract and test parallelizeBatches (#16596)

* [kbn-build] Extract and test parallelizeBatches

* Add test for rejects

* Simplify test
This commit is contained in:
Kim Joar Bekkelund 2018-02-12 12:46:26 +01:00 committed by GitHub
parent a75db2ff53
commit 7e1bb7be50
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 438 additions and 369 deletions

File diff suppressed because one or more lines are too long

View file

@ -2,6 +2,7 @@ import chalk from 'chalk';
import { topologicallyBatchProjects } from '../utils/projects';
import { linkProjectExecutables } from '../utils/link_project_executables';
import { parallelizeBatches } from '../utils/parallelize';
export const name = 'bootstrap';
export const description = 'Install dependencies and crosslink projects';
@ -46,13 +47,3 @@ export async function run(projects, projectGraph, { options }) {
console.log(chalk.green.bold('\nBootstrapping completed!\n'));
}
async function parallelizeBatches(batchedProjects, fn) {
for (const batch of batchedProjects) {
const running = batch.map(pkg => fn(pkg));
// We need to make sure the entire batch has completed before we can move on
// to the next batch
await Promise.all(running);
}
}

View file

@ -1,6 +1,7 @@
import chalk from 'chalk';
import { topologicallyBatchProjects } from '../utils/projects';
import { parallelizeBatches } from '../utils/parallelize';
export const name = 'run';
export const description =
@ -31,13 +32,3 @@ export async function run(projects, projectGraph, { extraArgs }) {
}
});
}
async function parallelizeBatches(batchedProjects, fn) {
for (const batch of batchedProjects) {
const running = batch.map(pkg => fn(pkg));
// We need to make sure the entire batch has completed before we can move on
// to the next batch
await Promise.all(running);
}
}

View file

@ -0,0 +1,9 @@
export async function parallelizeBatches(batches, fn) {
for (const batch of batches) {
const running = batch.map(obj => fn(obj));
// We need to make sure the entire batch has completed before we can move on
// to the next batch
await Promise.all(running);
}
}

View file

@ -0,0 +1,79 @@
import { parallelizeBatches } from './parallelize';
// As promises resolve async, we use this helper to wait for all promises that
// have been resolved to complete (aka call `then`).
const tick = () =>
new Promise(resolve => {
setTimeout(resolve, 0);
});
test('parallelizes batches', async () => {
const foo = createPromiseWithResolve();
const bar = createPromiseWithResolve();
const baz = createPromiseWithResolve();
const batches = [[foo, bar], [baz]];
const parallelize = parallelizeBatches(batches, obj => {
obj.called = true;
return obj.promise;
});
const completed = [];
parallelize.then(() => {
completed.push('parallelizeBatches');
});
foo.promise.then(() => {
completed.push('foo');
});
bar.promise.then(() => {
completed.push('bar');
});
baz.promise.then(() => {
completed.push('baz');
});
expect(foo.called).toBe(true);
expect(bar.called).toBe(true);
expect(baz.called).toBe(false);
expect(completed).toEqual([]);
bar.resolve();
await tick();
expect(completed).toEqual(['bar']);
expect(baz.called).toBe(false);
foo.resolve();
await tick();
expect(completed).toEqual(['bar', 'foo']);
expect(baz.called).toBe(true);
baz.resolve();
await tick();
expect(completed).toEqual(['bar', 'foo', 'baz', 'parallelizeBatches']);
});
test('rejects if any promise rejects', async () => {
const foo = createPromiseWithResolve();
const bar = createPromiseWithResolve();
const baz = createPromiseWithResolve();
const batches = [[foo, bar], [baz]];
const parallelize = parallelizeBatches(batches, obj => obj.promise);
foo.reject(new Error('foo failed'));
await expect(parallelize).rejects.toThrow('foo failed');
});
function createPromiseWithResolve() {
let resolve;
let reject;
const promise = new Promise((_resolve, _reject) => {
resolve = _resolve;
reject = _reject;
});
return { promise, resolve, reject, called: false };
}