Skip to content

Commit ecdbe72

Browse files
committed
fix(@angular-devkit/architect): complete builders on the next event loop iteration
Waiting to complete the builder until the next tick allows the logging subscription to flush and provide queued logging entries to the builder consumer.
1 parent f868953 commit ecdbe72

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

packages/angular_devkit/architect/src/create-builder.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import { analytics, experimental, json, logging } from '@angular-devkit/core';
1010
import { Observable, Subscription, from, isObservable, of, throwError } from 'rxjs';
11-
import { tap } from 'rxjs/operators';
11+
import { mergeMap, tap } from 'rxjs/operators';
1212
import {
1313
BuilderContext,
1414
BuilderHandlerFn,
@@ -223,6 +223,12 @@ export function createBuilder<OptT = json.JsonObject, OutT extends BuilderOutput
223223
progress({ state: BuilderProgressState.Running, current: total }, context);
224224
progress({ state: BuilderProgressState.Stopped }, context);
225225
}),
226+
mergeMap(async (value) => {
227+
// Allow the log queue to flush
228+
await new Promise<void>(setImmediate);
229+
230+
return value;
231+
}),
226232
)
227233
.subscribe(
228234
(message) => observer.next(message as OutT),

packages/angular_devkit/architect/src/index_spec.ts

+31-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import { json, schema } from '@angular-devkit/core';
9+
import { json, logging, schema } from '@angular-devkit/core';
1010
import { timer } from 'rxjs';
1111
import { map, take, tap, toArray } from 'rxjs/operators';
1212
import { promisify } from 'util';
@@ -206,6 +206,36 @@ describe('architect', () => {
206206
expect(all.length).toBe(10);
207207
});
208208

209+
it('propagates all logging entries', async () => {
210+
const logCount = 100;
211+
212+
testArchitectHost.addBuilder(
213+
'package:test-logging',
214+
createBuilder(async (_, context) => {
215+
for (let i = 0; i < logCount; ++i) {
216+
context.logger.info(i.toString());
217+
}
218+
219+
return { success: true };
220+
}),
221+
);
222+
223+
const logger = new logging.Logger('test-logger');
224+
const logs: string[] = [];
225+
logger.subscribe({
226+
next(entry) {
227+
logs.push(entry.message);
228+
},
229+
});
230+
const run = await architect.scheduleBuilder('package:test-logging', {}, { logger });
231+
expect(await run.result).toEqual(jasmine.objectContaining({ success: true }));
232+
await run.stop();
233+
234+
for (let i = 0; i < logCount; ++i) {
235+
expect(logs[i]).toBe(i.toString());
236+
}
237+
});
238+
209239
it('reports errors in the builder', async () => {
210240
testArchitectHost.addBuilder(
211241
'package:error',

0 commit comments

Comments
 (0)