From 5f4436d43385b31743830f448a007b4cd7afe613 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 22 Sep 2017 14:44:26 -0700 Subject: [PATCH] Keep a small reserve of tasks to not-batch, so all threads can have always have an initial task (#18696) * Keep a small reserve of tasks to not-batch, so all threads can have an initial task" * Assign no weight to new tests, but still place them at the end of the list --- src/harness/parallel/host.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/harness/parallel/host.ts b/src/harness/parallel/host.ts index 9f5ebdd790..764e763566 100644 --- a/src/harness/parallel/host.ts +++ b/src/harness/parallel/host.ts @@ -44,7 +44,8 @@ namespace Harness.Parallel.Host { console.log("Discovering tests..."); const discoverStart = +(new Date()); const { statSync }: { statSync(path: string): { size: number }; } = require("fs"); - const tasks: { runner: TestRunnerKind, file: string, size: number }[] = []; + let tasks: { runner: TestRunnerKind, file: string, size: number }[] = []; + const newTasks: { runner: TestRunnerKind, file: string, size: number }[] = []; const perfData = readSavedPerfData(); let totalCost = 0; let unknownValue: string | undefined; @@ -60,8 +61,10 @@ namespace Harness.Parallel.Host { const hashedName = hashName(runner.kind(), file); size = perfData[hashedName]; if (size === undefined) { - size = Number.MAX_SAFE_INTEGER; + size = 0; unknownValue = hashedName; + newTasks.push({ runner: runner.kind(), file, size }); + continue; } } tasks.push({ runner: runner.kind(), file, size }); @@ -69,6 +72,7 @@ namespace Harness.Parallel.Host { } } tasks.sort((a, b) => a.size - b.size); + tasks = tasks.concat(newTasks); // 1 fewer batches than threads to account for unittests running on the final thread const batchCount = runners.length === 1 ? workerCount : workerCount - 1; const packfraction = 0.9; @@ -174,7 +178,7 @@ namespace Harness.Parallel.Host { let scheduledTotal = 0; batcher: while (true) { for (let i = 0; i < batchCount; i++) { - if (tasks.length === 0) { + if (tasks.length <= workerCount) { // Keep a small reserve even in the suboptimally packed case console.log(`Suboptimal packing detected: no tests remain to be stolen. Reduce packing fraction from ${packfraction} to fix.`); break batcher; } @@ -213,7 +217,9 @@ namespace Harness.Parallel.Host { worker.send({ type: "batch", payload }); } else { // Unittest thread - send off just one test - worker.send({ type: "test", payload: tasks.pop() }); + const payload = tasks.pop(); + ts.Debug.assert(!!payload); // The reserve kept above should ensure there is always an initial task available, even in suboptimal scenarios + worker.send({ type: "test", payload }); } } }