nx 20.8.0-canary.20250412-07ad2d7 → 20.8.0
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
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "nx",
|
3
|
-
"version": "20.8.0
|
3
|
+
"version": "20.8.0",
|
4
4
|
"private": false,
|
5
5
|
"description": "The core Nx plugin contains the core functionality of Nx like the project graph, nx commands and task orchestration.",
|
6
6
|
"repository": {
|
@@ -82,16 +82,16 @@
|
|
82
82
|
}
|
83
83
|
},
|
84
84
|
"optionalDependencies": {
|
85
|
-
"@nx/nx-darwin-arm64": "20.8.0
|
86
|
-
"@nx/nx-darwin-x64": "20.8.0
|
87
|
-
"@nx/nx-freebsd-x64": "20.8.0
|
88
|
-
"@nx/nx-linux-arm-gnueabihf": "20.8.0
|
89
|
-
"@nx/nx-linux-arm64-gnu": "20.8.0
|
90
|
-
"@nx/nx-linux-arm64-musl": "20.8.0
|
91
|
-
"@nx/nx-linux-x64-gnu": "20.8.0
|
92
|
-
"@nx/nx-linux-x64-musl": "20.8.0
|
93
|
-
"@nx/nx-win32-arm64-msvc": "20.8.0
|
94
|
-
"@nx/nx-win32-x64-msvc": "20.8.0
|
85
|
+
"@nx/nx-darwin-arm64": "20.8.0",
|
86
|
+
"@nx/nx-darwin-x64": "20.8.0",
|
87
|
+
"@nx/nx-freebsd-x64": "20.8.0",
|
88
|
+
"@nx/nx-linux-arm-gnueabihf": "20.8.0",
|
89
|
+
"@nx/nx-linux-arm64-gnu": "20.8.0",
|
90
|
+
"@nx/nx-linux-arm64-musl": "20.8.0",
|
91
|
+
"@nx/nx-linux-x64-gnu": "20.8.0",
|
92
|
+
"@nx/nx-linux-x64-musl": "20.8.0",
|
93
|
+
"@nx/nx-win32-arm64-msvc": "20.8.0",
|
94
|
+
"@nx/nx-win32-x64-msvc": "20.8.0"
|
95
95
|
},
|
96
96
|
"nx-migrations": {
|
97
97
|
"migrations": "./migrations.json",
|
Binary file
|
@@ -8,10 +8,12 @@ export declare class ForkedProcessTaskRunner {
|
|
8
8
|
cliPath: string;
|
9
9
|
private readonly verbose;
|
10
10
|
private processes;
|
11
|
+
private finishedProcesses;
|
11
12
|
private pseudoTerminal;
|
12
13
|
constructor(options: DefaultTasksRunnerOptions);
|
13
14
|
init(): Promise<void>;
|
14
15
|
forkProcessForBatch({ executorName, taskGraph: batchTaskGraph }: Batch, projectGraph: ProjectGraph, fullTaskGraph: TaskGraph, env: NodeJS.ProcessEnv): Promise<BatchResults>;
|
16
|
+
cleanUpBatchProcesses(): void;
|
15
17
|
forkProcessLegacy(task: Task, { temporaryOutputPath, streamOutput, pipeOutput, taskGraph, env, }: {
|
16
18
|
temporaryOutputPath: string;
|
17
19
|
streamOutput: boolean;
|
@@ -20,6 +20,7 @@ class ForkedProcessTaskRunner {
|
|
20
20
|
this.cliPath = (0, utils_1.getCliPath)();
|
21
21
|
this.verbose = process.env.NX_VERBOSE_LOGGING === 'true';
|
22
22
|
this.processes = new Set();
|
23
|
+
this.finishedProcesses = new Set();
|
23
24
|
this.pseudoTerminal = pseudo_terminal_1.PseudoTerminal.isSupported()
|
24
25
|
? (0, pseudo_terminal_1.getPseudoTerminal)()
|
25
26
|
: null;
|
@@ -33,6 +34,7 @@ class ForkedProcessTaskRunner {
|
|
33
34
|
// TODO: vsavkin delegate terminal output printing
|
34
35
|
forkProcessForBatch({ executorName, taskGraph: batchTaskGraph }, projectGraph, fullTaskGraph, env) {
|
35
36
|
return new Promise((res, rej) => {
|
37
|
+
let p;
|
36
38
|
try {
|
37
39
|
const count = Object.keys(batchTaskGraph.tasks).length;
|
38
40
|
if (count > 1) {
|
@@ -42,7 +44,7 @@ class ForkedProcessTaskRunner {
|
|
42
44
|
const args = (0, utils_1.getPrintableCommandArgsForTask)(Object.values(batchTaskGraph.tasks)[0]);
|
43
45
|
output_1.output.logCommand(args.join(' '));
|
44
46
|
}
|
45
|
-
|
47
|
+
p = (0, child_process_1.fork)(workerPath, {
|
46
48
|
stdio: ['inherit', 'inherit', 'inherit', 'ipc'],
|
47
49
|
env,
|
48
50
|
});
|
@@ -52,20 +54,18 @@ class ForkedProcessTaskRunner {
|
|
52
54
|
if (code === null)
|
53
55
|
code = (0, exit_codes_1.signalToCode)(signal);
|
54
56
|
if (code !== 0) {
|
55
|
-
const results = {};
|
56
|
-
for (const rootTaskId of batchTaskGraph.roots) {
|
57
|
-
results[rootTaskId] = {
|
58
|
-
success: false,
|
59
|
-
terminalOutput: '',
|
60
|
-
};
|
61
|
-
}
|
62
57
|
rej(new Error(`"${executorName}" exited unexpectedly with code: ${code}`));
|
63
58
|
}
|
64
59
|
});
|
60
|
+
p.on('error', (err) => {
|
61
|
+
this.processes.delete(p);
|
62
|
+
rej(err || new Error(`"${executorName}" exited unexpectedly`));
|
63
|
+
});
|
65
64
|
p.on('message', (message) => {
|
66
65
|
switch (message.type) {
|
67
66
|
case batch_messages_1.BatchMessageType.CompleteBatchExecution: {
|
68
67
|
res(message.results);
|
68
|
+
this.finishedProcesses.add(p);
|
69
69
|
break;
|
70
70
|
}
|
71
71
|
case batch_messages_1.BatchMessageType.RunTasks: {
|
@@ -90,9 +90,23 @@ class ForkedProcessTaskRunner {
|
|
90
90
|
}
|
91
91
|
catch (e) {
|
92
92
|
rej(e);
|
93
|
+
if (p) {
|
94
|
+
this.processes.delete(p);
|
95
|
+
p.kill();
|
96
|
+
}
|
93
97
|
}
|
94
98
|
});
|
95
99
|
}
|
100
|
+
cleanUpBatchProcesses() {
|
101
|
+
if (this.finishedProcesses.size > 0) {
|
102
|
+
this.finishedProcesses.forEach((p) => {
|
103
|
+
if ('connected' in p ? p.connected : p.isAlive) {
|
104
|
+
p.kill();
|
105
|
+
}
|
106
|
+
});
|
107
|
+
this.finishedProcesses.clear();
|
108
|
+
}
|
109
|
+
}
|
96
110
|
async forkProcessLegacy(task, { temporaryOutputPath, streamOutput, pipeOutput, taskGraph, env, }) {
|
97
111
|
return pipeOutput
|
98
112
|
? await this.forkProcessPipeOutputCapture(task, {
|
@@ -157,6 +171,7 @@ class ForkedProcessTaskRunner {
|
|
157
171
|
});
|
158
172
|
return new Promise((res) => {
|
159
173
|
p.onExit((code) => {
|
174
|
+
this.processes.delete(p);
|
160
175
|
// If the exit code is greater than 128, it's a special exit code for a signal
|
161
176
|
if (code >= 128) {
|
162
177
|
process.exit(code);
|
@@ -227,7 +242,7 @@ class ForkedProcessTaskRunner {
|
|
227
242
|
p.stderr.on('data', (chunk) => {
|
228
243
|
outWithErr.push(chunk.toString());
|
229
244
|
});
|
230
|
-
p.
|
245
|
+
p.once('exit', (code, signal) => {
|
231
246
|
this.processes.delete(p);
|
232
247
|
if (code === null)
|
233
248
|
code = (0, exit_codes_1.signalToCode)(signal);
|
@@ -272,7 +287,8 @@ class ForkedProcessTaskRunner {
|
|
272
287
|
taskGraph,
|
273
288
|
isVerbose: this.verbose,
|
274
289
|
});
|
275
|
-
p.
|
290
|
+
p.once('exit', (code, signal) => {
|
291
|
+
this.processes.delete(p);
|
276
292
|
if (code === null)
|
277
293
|
code = (0, exit_codes_1.signalToCode)(signal);
|
278
294
|
// we didn't print any output as we were running the command
|
@@ -317,8 +333,7 @@ class ForkedProcessTaskRunner {
|
|
317
333
|
process.send(message);
|
318
334
|
});
|
319
335
|
}
|
320
|
-
|
321
|
-
process.on('message', (message) => {
|
336
|
+
const messageHandler = (message) => {
|
322
337
|
// this.publisher.publish(message.toString());
|
323
338
|
if (this.pseudoTerminal) {
|
324
339
|
this.pseudoTerminal.sendMessageToChildren(message);
|
@@ -328,39 +343,34 @@ class ForkedProcessTaskRunner {
|
|
328
343
|
p.send(message);
|
329
344
|
}
|
330
345
|
});
|
331
|
-
}
|
332
|
-
//
|
333
|
-
process.on('
|
346
|
+
};
|
347
|
+
// When the nx process gets a message, it will be sent into the task's process
|
348
|
+
process.on('message', messageHandler);
|
349
|
+
const cleanUp = (signal) => {
|
334
350
|
this.processes.forEach((p) => {
|
335
351
|
if ('connected' in p ? p.connected : p.isAlive) {
|
336
|
-
p.kill();
|
352
|
+
p.kill(signal);
|
337
353
|
}
|
338
354
|
});
|
355
|
+
process.off('message', messageHandler);
|
356
|
+
this.cleanUpBatchProcesses();
|
357
|
+
};
|
358
|
+
// Terminate any task processes on exit
|
359
|
+
process.once('exit', () => {
|
360
|
+
cleanUp();
|
339
361
|
});
|
340
|
-
process.
|
341
|
-
|
342
|
-
if ('connected' in p ? p.connected : p.isAlive) {
|
343
|
-
p.kill('SIGTERM');
|
344
|
-
}
|
345
|
-
});
|
362
|
+
process.once('SIGINT', () => {
|
363
|
+
cleanUp('SIGTERM');
|
346
364
|
// we exit here because we don't need to write anything to cache.
|
347
365
|
process.exit((0, exit_codes_1.signalToCode)('SIGINT'));
|
348
366
|
});
|
349
|
-
process.
|
350
|
-
|
351
|
-
if ('connected' in p ? p.connected : p.isAlive) {
|
352
|
-
p.kill('SIGTERM');
|
353
|
-
}
|
354
|
-
});
|
367
|
+
process.once('SIGTERM', () => {
|
368
|
+
cleanUp('SIGTERM');
|
355
369
|
// no exit here because we expect child processes to terminate which
|
356
370
|
// will store results to the cache and will terminate this process
|
357
371
|
});
|
358
|
-
process.
|
359
|
-
|
360
|
-
if ('connected' in p ? p.connected : p.isAlive) {
|
361
|
-
p.kill('SIGTERM');
|
362
|
-
}
|
363
|
-
});
|
372
|
+
process.once('SIGHUP', () => {
|
373
|
+
cleanUp('SIGTERM');
|
364
374
|
// no exit here because we expect child processes to terminate which
|
365
375
|
// will store results to the cache and will terminate this process
|
366
376
|
});
|
@@ -171,6 +171,7 @@ class TaskOrchestrator {
|
|
171
171
|
results.push(...batchResults);
|
172
172
|
}
|
173
173
|
await this.postRunSteps(tasks, results, doNotSkipCache, { groupId });
|
174
|
+
this.forkedProcessTaskRunner.cleanUpBatchProcesses();
|
174
175
|
const tasksCompleted = taskEntries.filter(([taskId]) => this.completedTasks[taskId]);
|
175
176
|
// Batch is still not done, run it again
|
176
177
|
if (tasksCompleted.length !== taskEntries.length) {
|