nx 21.0.0-canary.20250422-8619c1d → 21.0.0-canary.20250424-e23b25f
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +11 -11
- package/src/command-line/init/configure-plugins.js +5 -3
- package/src/command-line/init/implementation/utils.d.ts +2 -1
- package/src/command-line/init/implementation/utils.js +2 -1
- package/src/command-line/init/init-v2.js +8 -7
- package/src/core/graph/main.js +1 -1
- package/src/executors/run-commands/run-commands.impl.d.ts +1 -2
- package/src/executors/run-commands/run-commands.impl.js +1 -1
- package/src/executors/run-commands/running-tasks.d.ts +5 -2
- package/src/executors/run-commands/running-tasks.js +42 -6
- package/src/native/index.d.ts +4 -1
- package/src/native/nx.wasm32-wasi.wasm +0 -0
- package/src/tasks-runner/default-tasks-runner.js +1 -1
- package/src/tasks-runner/forked-process-task-runner.js +3 -0
- package/src/tasks-runner/init-tasks-runner.js +2 -1
- package/src/tasks-runner/life-cycle.d.ts +6 -2
- package/src/tasks-runner/life-cycle.js +16 -2
- package/src/tasks-runner/life-cycles/tui-summary-life-cycle.d.ts +2 -1
- package/src/tasks-runner/life-cycles/tui-summary-life-cycle.js +16 -10
- package/src/tasks-runner/run-command.d.ts +2 -1
- package/src/tasks-runner/run-command.js +14 -6
- package/src/tasks-runner/running-tasks/node-child-process.js +4 -11
- package/src/tasks-runner/running-tasks/running-task.d.ts +3 -0
- package/src/tasks-runner/running-tasks/shared-running-task.d.ts +14 -0
- package/src/tasks-runner/running-tasks/shared-running-task.js +30 -0
- package/src/tasks-runner/task-orchestrator.d.ts +6 -3
- package/src/tasks-runner/task-orchestrator.js +79 -23
- package/src/tasks-runner/tasks-runner.d.ts +1 -0
- package/src/tasks-runner/tasks-schedule.d.ts +1 -0
- package/src/tasks-runner/tasks-schedule.js +9 -0
- package/src/tasks-runner/utils.js +2 -0
@@ -21,11 +21,13 @@ const noop_child_process_1 = require("./running-tasks/noop-child-process");
|
|
21
21
|
const task_env_1 = require("./task-env");
|
22
22
|
const tasks_schedule_1 = require("./tasks-schedule");
|
23
23
|
const utils_1 = require("./utils");
|
24
|
+
const shared_running_task_1 = require("./running-tasks/shared-running-task");
|
24
25
|
class TaskOrchestrator {
|
25
26
|
// endregion internal state
|
26
|
-
constructor(hasher, initiatingProject, projectGraph, taskGraph, nxJson, options, bail, daemon, outputStyle, taskGraphForHashing = taskGraph) {
|
27
|
+
constructor(hasher, initiatingProject, initiatingTasks, projectGraph, taskGraph, nxJson, options, bail, daemon, outputStyle, taskGraphForHashing = taskGraph) {
|
27
28
|
this.hasher = hasher;
|
28
29
|
this.initiatingProject = initiatingProject;
|
30
|
+
this.initiatingTasks = initiatingTasks;
|
29
31
|
this.projectGraph = projectGraph;
|
30
32
|
this.taskGraph = taskGraph;
|
31
33
|
this.nxJson = nxJson;
|
@@ -43,6 +45,7 @@ class TaskOrchestrator {
|
|
43
45
|
// region internal state
|
44
46
|
this.batchEnv = (0, task_env_1.getEnvVariablesForBatchProcess)(this.options.skipNxCache, this.options.captureStderr);
|
45
47
|
this.reverseTaskDeps = (0, utils_1.calculateReverseDeps)(this.taskGraph);
|
48
|
+
this.initializingTaskIds = new Set(this.initiatingTasks.map((t) => t.id));
|
46
49
|
this.processedTasks = new Map();
|
47
50
|
this.processedBatches = new Map();
|
48
51
|
this.completedTasks = {};
|
@@ -50,7 +53,6 @@ class TaskOrchestrator {
|
|
50
53
|
this.groups = [];
|
51
54
|
this.bailed = false;
|
52
55
|
this.runningContinuousTasks = new Map();
|
53
|
-
this.cleaningUp = false;
|
54
56
|
}
|
55
57
|
async init() {
|
56
58
|
// Init the ForkedProcessTaskRunner, TasksSchedule, and Cache
|
@@ -300,9 +302,17 @@ class TaskOrchestrator {
|
|
300
302
|
const runningTask = await (0, run_commands_impl_1.runCommands)(runCommandsOptions, {
|
301
303
|
root: workspace_root_1.workspaceRoot, // only root is needed in runCommands
|
302
304
|
});
|
303
|
-
if (this.tuiEnabled
|
304
|
-
|
305
|
-
|
305
|
+
if (this.tuiEnabled) {
|
306
|
+
if (runningTask instanceof pseudo_terminal_1.PseudoTtyProcess) {
|
307
|
+
// This is an external of a the pseudo terminal where a task is running and can be passed to the TUI
|
308
|
+
this.options.lifeCycle.registerRunningTask(task.id, runningTask.getParserAndWriter());
|
309
|
+
}
|
310
|
+
else {
|
311
|
+
this.options.lifeCycle.registerRunningTaskWithEmptyParser(task.id);
|
312
|
+
runningTask.onOutput((output) => {
|
313
|
+
this.options.lifeCycle.appendTaskOutput(task.id, output);
|
314
|
+
});
|
315
|
+
}
|
306
316
|
}
|
307
317
|
if (!streamOutput) {
|
308
318
|
if (runningTask instanceof pseudo_terminal_1.PseudoTtyProcess) {
|
@@ -350,9 +360,17 @@ class TaskOrchestrator {
|
|
350
360
|
else {
|
351
361
|
// cache prep
|
352
362
|
const runningTask = await this.runTaskInForkedProcess(task, env, pipeOutput, temporaryOutputPath, streamOutput);
|
353
|
-
if (this.tuiEnabled
|
354
|
-
|
355
|
-
|
363
|
+
if (this.tuiEnabled) {
|
364
|
+
if (runningTask instanceof pseudo_terminal_1.PseudoTtyProcess) {
|
365
|
+
// This is an external of a the pseudo terminal where a task is running and can be passed to the TUI
|
366
|
+
this.options.lifeCycle.registerRunningTask(task.id, runningTask.getParserAndWriter());
|
367
|
+
}
|
368
|
+
else if ('onOutput' in runningTask) {
|
369
|
+
this.options.lifeCycle.registerRunningTaskWithEmptyParser(task.id);
|
370
|
+
runningTask.onOutput((output) => {
|
371
|
+
this.options.lifeCycle.appendTaskOutput(task.id, output);
|
372
|
+
});
|
373
|
+
}
|
356
374
|
}
|
357
375
|
return runningTask;
|
358
376
|
}
|
@@ -397,15 +415,27 @@ class TaskOrchestrator {
|
|
397
415
|
if (this.tuiEnabled) {
|
398
416
|
this.options.lifeCycle.setTaskStatus(task.id, 8 /* NativeTaskStatus.Shared */);
|
399
417
|
}
|
418
|
+
const runningTask = new shared_running_task_1.SharedRunningTask(this.runningTasksService, task.id);
|
419
|
+
this.runningContinuousTasks.set(task.id, runningTask);
|
420
|
+
runningTask.onExit(() => {
|
421
|
+
this.runningContinuousTasks.delete(task.id);
|
422
|
+
});
|
400
423
|
// task is already running by another process, we schedule the next tasks
|
401
424
|
// and release the threads
|
402
425
|
await this.scheduleNextTasksAndReleaseThreads();
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
426
|
+
if (this.initializingTaskIds.has(task.id)) {
|
427
|
+
await new Promise((res) => {
|
428
|
+
runningTask.onExit((code) => {
|
429
|
+
if (!this.tuiEnabled) {
|
430
|
+
if (code > 128) {
|
431
|
+
process.exit(code);
|
432
|
+
}
|
433
|
+
}
|
434
|
+
res();
|
435
|
+
});
|
436
|
+
});
|
437
|
+
}
|
438
|
+
return runningTask;
|
409
439
|
}
|
410
440
|
const taskSpecificEnv = await this.processedTasks.get(task.id);
|
411
441
|
await this.preRunSteps([task], { groupId });
|
@@ -425,14 +455,20 @@ class TaskOrchestrator {
|
|
425
455
|
this.runningContinuousTasks.set(task.id, childProcess);
|
426
456
|
childProcess.onExit(() => {
|
427
457
|
this.runningTasksService.removeRunningTask(task.id);
|
458
|
+
this.runningContinuousTasks.delete(task.id);
|
428
459
|
});
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
460
|
+
await this.scheduleNextTasksAndReleaseThreads();
|
461
|
+
if (this.initializingTaskIds.has(task.id)) {
|
462
|
+
await new Promise((res) => {
|
463
|
+
childProcess.onExit((code) => {
|
464
|
+
if (!this.tuiEnabled) {
|
465
|
+
if (code > 128) {
|
466
|
+
process.exit(code);
|
467
|
+
}
|
468
|
+
}
|
469
|
+
res();
|
470
|
+
});
|
471
|
+
});
|
436
472
|
}
|
437
473
|
return childProcess;
|
438
474
|
}
|
@@ -505,6 +541,7 @@ class TaskOrchestrator {
|
|
505
541
|
}
|
506
542
|
complete(taskResults) {
|
507
543
|
this.tasksSchedule.complete(taskResults.map(({ taskId }) => taskId));
|
544
|
+
this.cleanUpUnneededContinuousTasks();
|
508
545
|
for (const { taskId, status } of taskResults) {
|
509
546
|
if (this.completedTasks[taskId] === undefined) {
|
510
547
|
this.completedTasks[taskId] = status;
|
@@ -571,10 +608,10 @@ class TaskOrchestrator {
|
|
571
608
|
}
|
572
609
|
// endregion utils
|
573
610
|
async cleanup() {
|
574
|
-
this.cleaningUp = true;
|
575
611
|
await Promise.all(Array.from(this.runningContinuousTasks).map(async ([taskId, t]) => {
|
576
612
|
try {
|
577
|
-
|
613
|
+
await t.kill();
|
614
|
+
this.options.lifeCycle.setTaskStatus(taskId, 9 /* NativeTaskStatus.Stopped */);
|
578
615
|
}
|
579
616
|
catch (e) {
|
580
617
|
console.error(`Unable to terminate ${taskId}\nError:`, e);
|
@@ -584,6 +621,25 @@ class TaskOrchestrator {
|
|
584
621
|
}
|
585
622
|
}));
|
586
623
|
}
|
624
|
+
cleanUpUnneededContinuousTasks() {
|
625
|
+
const incompleteTasks = this.tasksSchedule.getIncompleteTasks();
|
626
|
+
const neededContinuousTasks = new Set(this.initializingTaskIds);
|
627
|
+
for (const task of incompleteTasks) {
|
628
|
+
const continuousDependencies = this.taskGraph.continuousDependencies[task.id];
|
629
|
+
for (const continuousDependency of continuousDependencies) {
|
630
|
+
neededContinuousTasks.add(continuousDependency);
|
631
|
+
}
|
632
|
+
}
|
633
|
+
for (const taskId of this.runningContinuousTasks.keys()) {
|
634
|
+
if (!neededContinuousTasks.has(taskId)) {
|
635
|
+
const runningTask = this.runningContinuousTasks.get(taskId);
|
636
|
+
if (runningTask) {
|
637
|
+
runningTask.kill();
|
638
|
+
this.options.lifeCycle.setTaskStatus(taskId, 9 /* NativeTaskStatus.Stopped */);
|
639
|
+
}
|
640
|
+
}
|
641
|
+
}
|
642
|
+
}
|
587
643
|
}
|
588
644
|
exports.TaskOrchestrator = TaskOrchestrator;
|
589
645
|
function getThreadCount(options, taskGraph) {
|
@@ -12,6 +12,7 @@ export type TaskStatus = 'success' | 'failure' | 'skipped' | 'local-cache-kept-e
|
|
12
12
|
export type TasksRunner<T = unknown> = (tasks: Task[], options: T, context?: {
|
13
13
|
target?: string;
|
14
14
|
initiatingProject?: string | null;
|
15
|
+
initiatingTasks: Task[];
|
15
16
|
projectGraph: ProjectGraph;
|
16
17
|
nxJson: NxJsonConfiguration;
|
17
18
|
nxArgs: NxArgs;
|
@@ -68,6 +68,15 @@ class TasksSchedule {
|
|
68
68
|
? this.scheduledBatches.shift()
|
69
69
|
: null;
|
70
70
|
}
|
71
|
+
getIncompleteTasks() {
|
72
|
+
const incompleteTasks = [];
|
73
|
+
for (const taskId in this.taskGraph.tasks) {
|
74
|
+
if (!this.completedTasks.has(taskId)) {
|
75
|
+
incompleteTasks.push(this.taskGraph.tasks[taskId]);
|
76
|
+
}
|
77
|
+
}
|
78
|
+
return incompleteTasks;
|
79
|
+
}
|
71
80
|
async scheduleTasks() {
|
72
81
|
if (this.options.batch || process.env.NX_BATCH_MODE === 'true') {
|
73
82
|
await this.scheduleBatches();
|
@@ -374,6 +374,8 @@ function shouldStreamOutput(task, initiatingProject) {
|
|
374
374
|
return false;
|
375
375
|
if (process.env.NX_STREAM_OUTPUT === 'true')
|
376
376
|
return true;
|
377
|
+
if (process.env.NX_STREAM_OUTPUT === 'false')
|
378
|
+
return false;
|
377
379
|
if (longRunningTask(task))
|
378
380
|
return true;
|
379
381
|
if (task.target.project === initiatingProject)
|