@@ -10,13 +10,12 @@ import {
1010 TextRewriterTransform
1111} from '@rushstack/terminal' ;
1212import { StreamCollator , CollatedTerminal , CollatedWriter } from '@rushstack/stream-collator' ;
13- import { AlreadyReportedError , NewlineKind , InternalError , Sort } from '@rushstack/node-core-library' ;
13+ import { AlreadyReportedError , NewlineKind , InternalError , Sort , Async } from '@rushstack/node-core-library' ;
1414
1515import { AsyncOperationQueue , IOperationSortFunction } from './AsyncOperationQueue' ;
1616import { Operation } from './Operation' ;
1717import { OperationStatus } from './OperationStatus' ;
1818import { IOperationExecutionRecordContext , OperationExecutionRecord } from './OperationExecutionRecord' ;
19- import { OperationError } from './OperationError' ;
2019
2120export interface IOperationExecutionManagerOptions {
2221 quietMode : boolean ;
@@ -205,18 +204,22 @@ export class OperationExecutionManager {
205204 } ;
206205 const executionQueue : AsyncOperationQueue = new AsyncOperationQueue ( this . _executionRecords , prioritySort ) ;
207206
208- // Iterate in parallel with maxParallelism concurrent lanes
209- await Promise . all (
210- Array . from ( { length : maxParallelism } , async ( unused : undefined , index : number ) : Promise < void > => {
211- // laneId can be used in logging to examine concurrency
212- const laneId : number = index + 1 ;
213- // The executionQueue is a singular async iterable that stalls until an operation is available, and marks itself
214- // done when the queue is empty.
215- for await ( const operations of executionQueue ) {
216- // Take an operation, execute it, wait for it to finish, wait for a new operations
217- await this . _executeOperationAsync ( operations , laneId ) ;
218- }
219- } )
207+ // This function is a callback because it may write to the collatedWriter before
208+ // operation.executeAsync returns (and cleans up the writer)
209+ const onOperationComplete : ( record : OperationExecutionRecord ) => void = (
210+ record : OperationExecutionRecord
211+ ) => {
212+ this . _onOperationComplete ( record ) ;
213+ } ;
214+
215+ await Async . forEachAsync (
216+ executionQueue ,
217+ async ( operation : OperationExecutionRecord ) => {
218+ await operation . executeAsync ( onOperationComplete ) ;
219+ } ,
220+ {
221+ concurrency : maxParallelism
222+ }
220223 ) ;
221224
222225 this . _printOperationStatus ( ) ;
@@ -230,40 +233,18 @@ export class OperationExecutionManager {
230233 }
231234 }
232235
233- private async _executeOperationAsync ( operation : OperationExecutionRecord , tid : number ) : Promise < void > {
234- let result : OperationStatus = ( operation . status = OperationStatus . Executing ) ;
235- operation . stopwatch . start ( ) ;
236-
237- try {
238- result = await operation . runner . executeAsync ( operation ) ;
239-
240- // Only perform global state updates. Internal state updates are handled by Operation itself.
241- this . _handleOperationResult ( operation , result ) ;
242- } catch ( error ) {
243- const status : OperationStatus = OperationStatus . Failure ;
244- operation . error = error as OperationError ;
245- this . _handleOperationResult ( operation , status ) ;
246- } finally {
247- // Delegate cleanup.
248- // Calling `operation.collatedWriter` creates it if it didn't exist.
249- operation . finish ( ) ;
250- }
251- }
252-
253236 /**
254- * Applies the new status to an OperationExecutionRecord and propagates any relevant effects.
237+ * Handles the result of the operation and propagates any relevant effects.
255238 */
256- private _handleOperationResult ( record : OperationExecutionRecord , result : OperationStatus ) : void {
257- record . status = result ;
258-
259- const { runner, name } = record ;
239+ private _onOperationComplete ( record : OperationExecutionRecord ) : void {
240+ const { runner, name, status } = record ;
260241
261242 let blockCacheWrite : boolean = ! runner . isCacheWriteAllowed ;
262243 let blockSkip : boolean = ! runner . isSkipAllowed ;
263244
264245 const silent : boolean = runner . silent ;
265246
266- switch ( result ) {
247+ switch ( status ) {
267248 /**
268249 * This operation failed. Mark it as such and all reachable dependents as blocked.
269250 */
0 commit comments