@@ -44,7 +44,8 @@ namespace Harness.Parallel.Host {
44
44
console . log ( "Discovering tests..." ) ;
45
45
const discoverStart = + ( new Date ( ) ) ;
46
46
const { statSync } : { statSync ( path : string ) : { size : number } ; } = require ( "fs" ) ;
47
- const tasks : { runner : TestRunnerKind , file : string , size : number } [ ] = [ ] ;
47
+ let tasks : { runner : TestRunnerKind , file : string , size : number } [ ] = [ ] ;
48
+ const newTasks : { runner : TestRunnerKind , file : string , size : number } [ ] = [ ] ;
48
49
const perfData = readSavedPerfData ( ) ;
49
50
let totalCost = 0 ;
50
51
let unknownValue : string | undefined ;
@@ -60,15 +61,18 @@ namespace Harness.Parallel.Host {
60
61
const hashedName = hashName ( runner . kind ( ) , file ) ;
61
62
size = perfData [ hashedName ] ;
62
63
if ( size === undefined ) {
63
- size = Number . MAX_SAFE_INTEGER ;
64
+ size = 0 ;
64
65
unknownValue = hashedName ;
66
+ newTasks . push ( { runner : runner . kind ( ) , file, size } ) ;
67
+ continue ;
65
68
}
66
69
}
67
70
tasks . push ( { runner : runner . kind ( ) , file, size } ) ;
68
71
totalCost += size ;
69
72
}
70
73
}
71
74
tasks . sort ( ( a , b ) => a . size - b . size ) ;
75
+ tasks = tasks . concat ( newTasks ) ;
72
76
// 1 fewer batches than threads to account for unittests running on the final thread
73
77
const batchCount = runners . length === 1 ? workerCount : workerCount - 1 ;
74
78
const packfraction = 0.9 ;
@@ -174,7 +178,7 @@ namespace Harness.Parallel.Host {
174
178
let scheduledTotal = 0 ;
175
179
batcher: while ( true ) {
176
180
for ( let i = 0 ; i < batchCount ; i ++ ) {
177
- if ( tasks . length === 0 ) {
181
+ if ( tasks . length <= workerCount ) { // Keep a small reserve even in the suboptimally packed case
178
182
console . log ( `Suboptimal packing detected: no tests remain to be stolen. Reduce packing fraction from ${ packfraction } to fix.` ) ;
179
183
break batcher;
180
184
}
@@ -213,7 +217,9 @@ namespace Harness.Parallel.Host {
213
217
worker . send ( { type : "batch" , payload } ) ;
214
218
}
215
219
else { // Unittest thread - send off just one test
216
- worker . send ( { type : "test" , payload : tasks . pop ( ) } ) ;
220
+ const payload = tasks . pop ( ) ;
221
+ ts . Debug . assert ( ! ! payload ) ; // The reserve kept above should ensure there is always an initial task available, even in suboptimal scenarios
222
+ worker . send ( { type : "test" , payload } ) ;
217
223
}
218
224
}
219
225
}
0 commit comments