nx 20.5.0-canary.20250204-bc4ded0 → 21.0.0-beta.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.
Files changed (31) hide show
  1. package/package.json +12 -11
  2. package/src/command-line/graph/graph.js +2 -0
  3. package/src/commands-runner/get-command-projects.js +17 -2
  4. package/src/config/task-graph.d.ts +5 -0
  5. package/src/config/workspace-json-project-json.d.ts +4 -0
  6. package/src/executors/run-commands/run-commands.impl.d.ts +16 -13
  7. package/src/executors/run-commands/run-commands.impl.js +24 -263
  8. package/src/executors/run-commands/running-tasks.d.ts +38 -0
  9. package/src/executors/run-commands/running-tasks.js +349 -0
  10. package/src/native/index.d.ts +1 -0
  11. package/src/native/nx.wasm32-wasi.wasm +0 -0
  12. package/src/tasks-runner/create-task-graph.d.ts +3 -0
  13. package/src/tasks-runner/create-task-graph.js +36 -5
  14. package/src/tasks-runner/forked-process-task-runner.d.ts +6 -12
  15. package/src/tasks-runner/forked-process-task-runner.js +110 -263
  16. package/src/tasks-runner/init-tasks-runner.js +4 -0
  17. package/src/tasks-runner/pseudo-terminal.d.ts +7 -1
  18. package/src/tasks-runner/pseudo-terminal.js +26 -12
  19. package/src/tasks-runner/running-tasks/batch-process.d.ts +14 -0
  20. package/src/tasks-runner/running-tasks/batch-process.js +70 -0
  21. package/src/tasks-runner/running-tasks/node-child-process.d.ts +36 -0
  22. package/src/tasks-runner/running-tasks/node-child-process.js +184 -0
  23. package/src/tasks-runner/running-tasks/noop-child-process.d.ts +15 -0
  24. package/src/tasks-runner/running-tasks/noop-child-process.js +19 -0
  25. package/src/tasks-runner/running-tasks/running-task.d.ts +8 -0
  26. package/src/tasks-runner/running-tasks/running-task.js +6 -0
  27. package/src/tasks-runner/task-orchestrator.d.ts +7 -1
  28. package/src/tasks-runner/task-orchestrator.js +137 -82
  29. package/src/tasks-runner/tasks-schedule.js +5 -1
  30. package/src/tasks-runner/utils.d.ts +0 -8
  31. package/src/tasks-runner/utils.js +12 -4
@@ -3,15 +3,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ForkedProcessTaskRunner = void 0;
4
4
  const fs_1 = require("fs");
5
5
  const child_process_1 = require("child_process");
6
- const chalk = require("chalk");
7
6
  const output_1 = require("../utils/output");
8
7
  const utils_1 = require("./utils");
9
8
  const path_1 = require("path");
10
9
  const batch_messages_1 = require("./batch/batch-messages");
11
10
  const strip_indents_1 = require("../utils/strip-indents");
12
- const stream_1 = require("stream");
13
11
  const pseudo_terminal_1 = require("./pseudo-terminal");
14
12
  const exit_codes_1 = require("../utils/exit-codes");
13
+ const node_child_process_1 = require("./running-tasks/node-child-process");
14
+ const batch_process_1 = require("./running-tasks/batch-process");
15
15
  const forkScript = (0, path_1.join)(__dirname, './fork.js');
16
16
  const workerPath = (0, path_1.join)(__dirname, './batch/run-batch.js');
17
17
  class ForkedProcessTaskRunner {
@@ -31,76 +31,42 @@ class ForkedProcessTaskRunner {
31
31
  this.setupProcessEventListeners();
32
32
  }
33
33
  // TODO: vsavkin delegate terminal output printing
34
- forkProcessForBatch({ executorName, taskGraph: batchTaskGraph }, fullTaskGraph, env) {
35
- return new Promise((res, rej) => {
36
- try {
37
- const count = Object.keys(batchTaskGraph.tasks).length;
38
- if (count > 1) {
39
- output_1.output.logSingleLine(`Running ${output_1.output.bold(count)} ${output_1.output.bold('tasks')} with ${output_1.output.bold(executorName)}`);
40
- }
41
- else {
42
- const args = (0, utils_1.getPrintableCommandArgsForTask)(Object.values(batchTaskGraph.tasks)[0]);
43
- output_1.output.logCommand(args.join(' '));
44
- }
45
- const p = (0, child_process_1.fork)(workerPath, {
46
- stdio: ['inherit', 'inherit', 'inherit', 'ipc'],
47
- env,
48
- });
49
- this.processes.add(p);
50
- p.once('exit', (code, signal) => {
51
- this.processes.delete(p);
52
- if (code === null)
53
- code = (0, exit_codes_1.signalToCode)(signal);
54
- if (code !== 0) {
55
- const results = {};
56
- for (const rootTaskId of batchTaskGraph.roots) {
57
- results[rootTaskId] = {
58
- success: false,
59
- terminalOutput: '',
60
- };
61
- }
62
- rej(new Error(`"${executorName}" exited unexpectedly with code: ${code}`));
63
- }
64
- });
65
- p.on('message', (message) => {
66
- switch (message.type) {
67
- case batch_messages_1.BatchMessageType.CompleteBatchExecution: {
68
- res(message.results);
69
- break;
70
- }
71
- case batch_messages_1.BatchMessageType.RunTasks: {
72
- break;
73
- }
74
- default: {
75
- // Re-emit any non-batch messages from the task process
76
- if (process.send) {
77
- process.send(message);
78
- }
79
- }
80
- }
81
- });
82
- // Start the tasks
83
- p.send({
84
- type: batch_messages_1.BatchMessageType.RunTasks,
85
- executorName,
86
- batchTaskGraph,
87
- fullTaskGraph,
88
- });
89
- }
90
- catch (e) {
91
- rej(e);
92
- }
34
+ async forkProcessForBatch({ executorName, taskGraph: batchTaskGraph }, fullTaskGraph, env) {
35
+ const count = Object.keys(batchTaskGraph.tasks).length;
36
+ if (count > 1) {
37
+ output_1.output.logSingleLine(`Running ${output_1.output.bold(count)} ${output_1.output.bold('tasks')} with ${output_1.output.bold(executorName)}`);
38
+ }
39
+ else {
40
+ const args = (0, utils_1.getPrintableCommandArgsForTask)(Object.values(batchTaskGraph.tasks)[0]);
41
+ output_1.output.logCommand(args.join(' '));
42
+ }
43
+ const p = (0, child_process_1.fork)(workerPath, {
44
+ stdio: ['inherit', 'inherit', 'inherit', 'ipc'],
45
+ env,
46
+ });
47
+ const cp = new batch_process_1.BatchProcess(p, executorName);
48
+ this.processes.add(cp);
49
+ cp.onExit(() => {
50
+ this.processes.delete(cp);
51
+ });
52
+ // Start the tasks
53
+ cp.send({
54
+ type: batch_messages_1.BatchMessageType.RunTasks,
55
+ executorName,
56
+ batchTaskGraph,
57
+ fullTaskGraph,
93
58
  });
59
+ return cp;
94
60
  }
95
61
  async forkProcessLegacy(task, { temporaryOutputPath, streamOutput, pipeOutput, taskGraph, env, }) {
96
62
  return pipeOutput
97
- ? await this.forkProcessPipeOutputCapture(task, {
63
+ ? this.forkProcessWithPrefixAndNotTTY(task, {
98
64
  temporaryOutputPath,
99
65
  streamOutput,
100
66
  taskGraph,
101
67
  env,
102
68
  })
103
- : await this.forkProcessDirectOutputCapture(task, {
69
+ : this.forkProcessDirectOutputCapture(task, {
104
70
  temporaryOutputPath,
105
71
  streamOutput,
106
72
  taskGraph,
@@ -154,158 +120,96 @@ class ForkedProcessTaskRunner {
154
120
  p.onOutput((msg) => {
155
121
  terminalOutput += msg;
156
122
  });
157
- return new Promise((res) => {
158
- p.onExit((code) => {
159
- // If the exit code is greater than 128, it's a special exit code for a signal
160
- if (code >= 128) {
161
- process.exit(code);
162
- }
163
- this.writeTerminalOutput(temporaryOutputPath, terminalOutput);
164
- res({
165
- code,
166
- terminalOutput,
167
- });
168
- });
169
- });
170
- }
171
- forkProcessPipeOutputCapture(task, { streamOutput, temporaryOutputPath, taskGraph, env, }) {
172
- return this.forkProcessWithPrefixAndNotTTY(task, {
173
- streamOutput,
174
- temporaryOutputPath,
175
- taskGraph,
176
- env,
123
+ p.onExit((code) => {
124
+ if (code > 128) {
125
+ process.exit(code);
126
+ }
127
+ this.processes.delete(p);
128
+ this.writeTerminalOutput(temporaryOutputPath, terminalOutput);
177
129
  });
130
+ return p;
178
131
  }
179
132
  forkProcessWithPrefixAndNotTTY(task, { streamOutput, temporaryOutputPath, taskGraph, env, }) {
180
- return new Promise((res, rej) => {
181
- try {
182
- const args = (0, utils_1.getPrintableCommandArgsForTask)(task);
183
- if (streamOutput) {
184
- output_1.output.logCommand(args.join(' '));
185
- }
186
- const p = (0, child_process_1.fork)(this.cliPath, {
187
- stdio: ['inherit', 'pipe', 'pipe', 'ipc'],
188
- env,
189
- });
190
- this.processes.add(p);
191
- // Re-emit any messages from the task process
192
- p.on('message', (message) => {
193
- if (process.send) {
194
- process.send(message);
195
- }
196
- });
197
- // Send message to run the executor
198
- p.send({
199
- targetDescription: task.target,
200
- overrides: task.overrides,
201
- taskGraph,
202
- isVerbose: this.verbose,
203
- });
204
- if (streamOutput) {
205
- if (process.env.NX_PREFIX_OUTPUT === 'true') {
206
- const color = getColor(task.target.project);
207
- const prefixText = `${task.target.project}:`;
208
- p.stdout
209
- .pipe(logClearLineToPrefixTransformer(color.bold(prefixText) + ' '))
210
- .pipe(addPrefixTransformer(color.bold(prefixText)))
211
- .pipe(process.stdout);
212
- p.stderr
213
- .pipe(logClearLineToPrefixTransformer(color(prefixText) + ' '))
214
- .pipe(addPrefixTransformer(color(prefixText)))
215
- .pipe(process.stderr);
216
- }
217
- else {
218
- p.stdout.pipe(addPrefixTransformer()).pipe(process.stdout);
219
- p.stderr.pipe(addPrefixTransformer()).pipe(process.stderr);
220
- }
133
+ try {
134
+ const args = (0, utils_1.getPrintableCommandArgsForTask)(task);
135
+ if (streamOutput) {
136
+ output_1.output.logCommand(args.join(' '));
137
+ }
138
+ const p = (0, child_process_1.fork)(this.cliPath, {
139
+ stdio: ['inherit', 'pipe', 'pipe', 'ipc'],
140
+ env,
141
+ });
142
+ // Send message to run the executor
143
+ p.send({
144
+ targetDescription: task.target,
145
+ overrides: task.overrides,
146
+ taskGraph,
147
+ isVerbose: this.verbose,
148
+ });
149
+ const cp = new node_child_process_1.NodeChildProcessWithNonDirectOutput(p, {
150
+ streamOutput,
151
+ prefix: task.target.project,
152
+ });
153
+ this.processes.add(cp);
154
+ cp.onExit((code, terminalOutput) => {
155
+ this.processes.delete(cp);
156
+ if (!streamOutput) {
157
+ this.options.lifeCycle.printTaskTerminalOutput(task, code === 0 ? 'success' : 'failure', terminalOutput);
221
158
  }
222
- let outWithErr = [];
223
- p.stdout.on('data', (chunk) => {
224
- outWithErr.push(chunk.toString());
225
- });
226
- p.stderr.on('data', (chunk) => {
227
- outWithErr.push(chunk.toString());
228
- });
229
- p.on('exit', (code, signal) => {
230
- this.processes.delete(p);
231
- if (code === null)
232
- code = (0, exit_codes_1.signalToCode)(signal);
233
- // we didn't print any output as we were running the command
234
- // print all the collected output|
235
- const terminalOutput = outWithErr.join('');
159
+ this.writeTerminalOutput(temporaryOutputPath, terminalOutput);
160
+ });
161
+ return cp;
162
+ }
163
+ catch (e) {
164
+ console.error(e);
165
+ throw e;
166
+ }
167
+ }
168
+ forkProcessDirectOutputCapture(task, { streamOutput, temporaryOutputPath, taskGraph, env, }) {
169
+ try {
170
+ const args = (0, utils_1.getPrintableCommandArgsForTask)(task);
171
+ if (streamOutput) {
172
+ output_1.output.logCommand(args.join(' '));
173
+ }
174
+ const p = (0, child_process_1.fork)(this.cliPath, {
175
+ stdio: ['inherit', 'inherit', 'inherit', 'ipc'],
176
+ env,
177
+ });
178
+ const cp = new node_child_process_1.NodeChildProcessWithDirectOutput(p, temporaryOutputPath);
179
+ this.processes.add(cp);
180
+ // Send message to run the executor
181
+ p.send({
182
+ targetDescription: task.target,
183
+ overrides: task.overrides,
184
+ taskGraph,
185
+ isVerbose: this.verbose,
186
+ });
187
+ cp.onExit((code, signal) => {
188
+ this.processes.delete(cp);
189
+ // we didn't print any output as we were running the command
190
+ // print all the collected output
191
+ try {
192
+ const terminalOutput = cp.getTerminalOutput();
236
193
  if (!streamOutput) {
237
194
  this.options.lifeCycle.printTaskTerminalOutput(task, code === 0 ? 'success' : 'failure', terminalOutput);
238
195
  }
239
- this.writeTerminalOutput(temporaryOutputPath, terminalOutput);
240
- res({ code, terminalOutput });
241
- });
242
- }
243
- catch (e) {
244
- console.error(e);
245
- rej(e);
246
- }
247
- });
248
- }
249
- forkProcessDirectOutputCapture(task, { streamOutput, temporaryOutputPath, taskGraph, env, }) {
250
- return new Promise((res, rej) => {
251
- try {
252
- const args = (0, utils_1.getPrintableCommandArgsForTask)(task);
253
- if (streamOutput) {
254
- output_1.output.logCommand(args.join(' '));
255
196
  }
256
- const p = (0, child_process_1.fork)(this.cliPath, {
257
- stdio: ['inherit', 'inherit', 'inherit', 'ipc'],
258
- env,
259
- });
260
- this.processes.add(p);
261
- // Re-emit any messages from the task process
262
- p.on('message', (message) => {
263
- if (process.send) {
264
- process.send(message);
265
- }
266
- });
267
- // Send message to run the executor
268
- p.send({
269
- targetDescription: task.target,
270
- overrides: task.overrides,
271
- taskGraph,
272
- isVerbose: this.verbose,
273
- });
274
- p.on('exit', (code, signal) => {
275
- if (code === null)
276
- code = (0, exit_codes_1.signalToCode)(signal);
277
- // we didn't print any output as we were running the command
278
- // print all the collected output
279
- let terminalOutput = '';
280
- try {
281
- terminalOutput = this.readTerminalOutput(temporaryOutputPath);
282
- if (!streamOutput) {
283
- this.options.lifeCycle.printTaskTerminalOutput(task, code === 0 ? 'success' : 'failure', terminalOutput);
284
- }
285
- }
286
- catch (e) {
287
- console.log((0, strip_indents_1.stripIndents) `
197
+ catch (e) {
198
+ console.log((0, strip_indents_1.stripIndents) `
288
199
  Unable to print terminal output for Task "${task.id}".
289
200
  Task failed with Exit Code ${code} and Signal "${signal}".
290
201
 
291
202
  Received error message:
292
203
  ${e.message}
293
204
  `);
294
- }
295
- res({
296
- code,
297
- terminalOutput,
298
- });
299
- });
300
- }
301
- catch (e) {
302
- console.error(e);
303
- rej(e);
304
- }
305
- });
306
- }
307
- readTerminalOutput(outputPath) {
308
- return (0, fs_1.readFileSync)(outputPath).toString();
205
+ }
206
+ });
207
+ return cp;
208
+ }
209
+ catch (e) {
210
+ console.error(e);
211
+ throw e;
212
+ }
309
213
  }
310
214
  writeTerminalOutput(outputPath, content) {
311
215
  (0, fs_1.writeFileSync)(outputPath, content);
@@ -318,12 +222,11 @@ class ForkedProcessTaskRunner {
318
222
  }
319
223
  // When the nx process gets a message, it will be sent into the task's process
320
224
  process.on('message', (message) => {
321
- // this.publisher.publish(message.toString());
322
225
  if (this.pseudoTerminal) {
323
226
  this.pseudoTerminal.sendMessageToChildren(message);
324
227
  }
325
228
  this.processes.forEach((p) => {
326
- if ('connected' in p && p.connected) {
229
+ if ('send' in p) {
327
230
  p.send(message);
328
231
  }
329
232
  });
@@ -331,34 +234,26 @@ class ForkedProcessTaskRunner {
331
234
  // Terminate any task processes on exit
332
235
  process.on('exit', () => {
333
236
  this.processes.forEach((p) => {
334
- if ('connected' in p ? p.connected : p.isAlive) {
335
- p.kill();
336
- }
237
+ p.kill();
337
238
  });
338
239
  });
339
240
  process.on('SIGINT', () => {
340
241
  this.processes.forEach((p) => {
341
- if ('connected' in p ? p.connected : p.isAlive) {
342
- p.kill('SIGTERM');
343
- }
242
+ p.kill('SIGTERM');
344
243
  });
345
244
  // we exit here because we don't need to write anything to cache.
346
245
  process.exit((0, exit_codes_1.signalToCode)('SIGINT'));
347
246
  });
348
247
  process.on('SIGTERM', () => {
349
248
  this.processes.forEach((p) => {
350
- if ('connected' in p ? p.connected : p.isAlive) {
351
- p.kill('SIGTERM');
352
- }
249
+ p.kill('SIGTERM');
353
250
  });
354
251
  // no exit here because we expect child processes to terminate which
355
252
  // will store results to the cache and will terminate this process
356
253
  });
357
254
  process.on('SIGHUP', () => {
358
255
  this.processes.forEach((p) => {
359
- if ('connected' in p ? p.connected : p.isAlive) {
360
- p.kill('SIGTERM');
361
- }
256
+ p.kill('SIGTERM');
362
257
  });
363
258
  // no exit here because we expect child processes to terminate which
364
259
  // will store results to the cache and will terminate this process
@@ -366,51 +261,3 @@ class ForkedProcessTaskRunner {
366
261
  }
367
262
  }
368
263
  exports.ForkedProcessTaskRunner = ForkedProcessTaskRunner;
369
- const colors = [
370
- chalk.green,
371
- chalk.greenBright,
372
- chalk.red,
373
- chalk.redBright,
374
- chalk.cyan,
375
- chalk.cyanBright,
376
- chalk.yellow,
377
- chalk.yellowBright,
378
- chalk.magenta,
379
- chalk.magentaBright,
380
- ];
381
- function getColor(projectName) {
382
- let code = 0;
383
- for (let i = 0; i < projectName.length; ++i) {
384
- code += projectName.charCodeAt(i);
385
- }
386
- const colorIndex = code % colors.length;
387
- return colors[colorIndex];
388
- }
389
- /**
390
- * Prevents terminal escape sequence from clearing line prefix.
391
- */
392
- function logClearLineToPrefixTransformer(prefix) {
393
- let prevChunk = null;
394
- return new stream_1.Transform({
395
- transform(chunk, _encoding, callback) {
396
- if (prevChunk && prevChunk.toString() === '\x1b[2K') {
397
- chunk = chunk.toString().replace(/\x1b\[1G/g, (m) => m + prefix);
398
- }
399
- this.push(chunk);
400
- prevChunk = chunk;
401
- callback();
402
- },
403
- });
404
- }
405
- function addPrefixTransformer(prefix) {
406
- const newLineSeparator = process.platform.startsWith('win') ? '\r\n' : '\n';
407
- return new stream_1.Transform({
408
- transform(chunk, _encoding, callback) {
409
- const list = chunk.toString().split(/\r\n|[\n\v\f\r\x85\u2028\u2029]/g);
410
- list
411
- .filter(Boolean)
412
- .forEach((m) => this.push(prefix ? prefix + ' ' + m + newLineSeparator : m + newLineSeparator));
413
- callback();
414
- },
415
- });
416
- }
@@ -36,6 +36,10 @@ async function initTasksRunner(nxArgs) {
36
36
  acc[task.id] = [];
37
37
  return acc;
38
38
  }, {}),
39
+ continuousDependencies: opts.tasks.reduce((acc, task) => {
40
+ acc[task.id] = [];
41
+ return acc;
42
+ }, {}),
39
43
  };
40
44
  const taskResults = await (0, run_command_1.invokeTasksRunner)({
41
45
  tasks: opts.tasks,
@@ -31,8 +31,14 @@ export declare class PseudoTerminal {
31
31
  export declare class PseudoTtyProcess {
32
32
  private childProcess;
33
33
  isAlive: boolean;
34
- exitCallbacks: any[];
34
+ private exitCallbacks;
35
+ private outputCallbacks;
36
+ private terminalOutput;
35
37
  constructor(childProcess: ChildProcess);
38
+ getResults(): Promise<{
39
+ code: number;
40
+ terminalOutput: string;
41
+ }>;
36
42
  onExit(callback: (code: number) => void): void;
37
43
  onOutput(callback: (message: string) => void): void;
38
44
  kill(): void;
@@ -78,28 +78,42 @@ class PseudoTtyProcess {
78
78
  this.childProcess = childProcess;
79
79
  this.isAlive = true;
80
80
  this.exitCallbacks = [];
81
+ this.outputCallbacks = [];
82
+ this.terminalOutput = '';
83
+ childProcess.onOutput((output) => {
84
+ this.terminalOutput += output;
85
+ this.outputCallbacks.forEach((cb) => cb(output));
86
+ });
81
87
  childProcess.onExit((message) => {
82
88
  this.isAlive = false;
83
- const exitCode = messageToCode(message);
84
- this.exitCallbacks.forEach((cb) => cb(exitCode));
89
+ const code = messageToCode(message);
90
+ childProcess.cleanup();
91
+ this.exitCallbacks.forEach((cb) => cb(code));
92
+ });
93
+ }
94
+ async getResults() {
95
+ return new Promise((res) => {
96
+ this.onExit((code) => {
97
+ res({ code, terminalOutput: this.terminalOutput });
98
+ });
85
99
  });
86
100
  }
87
101
  onExit(callback) {
88
102
  this.exitCallbacks.push(callback);
89
103
  }
90
104
  onOutput(callback) {
91
- this.childProcess.onOutput(callback);
105
+ this.outputCallbacks.push(callback);
92
106
  }
93
107
  kill() {
94
- try {
95
- this.childProcess.kill();
96
- }
97
- catch {
98
- // when the child process completes before we explicitly call kill, this will throw
99
- // do nothing
100
- }
101
- finally {
102
- if (this.isAlive == true) {
108
+ if (this.isAlive) {
109
+ try {
110
+ this.childProcess.kill();
111
+ }
112
+ catch {
113
+ // when the child process completes before we explicitly call kill, this will throw
114
+ // do nothing
115
+ }
116
+ finally {
103
117
  this.isAlive = false;
104
118
  }
105
119
  }
@@ -0,0 +1,14 @@
1
+ import { BatchResults } from '../batch/batch-messages';
2
+ import { ChildProcess, Serializable } from 'child_process';
3
+ export declare class BatchProcess {
4
+ private childProcess;
5
+ private executorName;
6
+ private exitCallbacks;
7
+ private resultsCallbacks;
8
+ constructor(childProcess: ChildProcess, executorName: string);
9
+ onExit(cb: (code: number) => void): void;
10
+ onResults(cb: (results: BatchResults) => void): void;
11
+ getResults(): Promise<BatchResults>;
12
+ send(message: Serializable): void;
13
+ kill(signal?: NodeJS.Signals | number): void;
14
+ }
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BatchProcess = void 0;
4
+ const batch_messages_1 = require("../batch/batch-messages");
5
+ const exit_codes_1 = require("../../utils/exit-codes");
6
+ class BatchProcess {
7
+ constructor(childProcess, executorName) {
8
+ this.childProcess = childProcess;
9
+ this.executorName = executorName;
10
+ this.exitCallbacks = [];
11
+ this.resultsCallbacks = [];
12
+ this.childProcess.on('message', (message) => {
13
+ switch (message.type) {
14
+ case batch_messages_1.BatchMessageType.CompleteBatchExecution: {
15
+ for (const cb of this.resultsCallbacks) {
16
+ cb(message.results);
17
+ }
18
+ break;
19
+ }
20
+ case batch_messages_1.BatchMessageType.RunTasks: {
21
+ break;
22
+ }
23
+ default: {
24
+ // Re-emit any non-batch messages from the task process
25
+ if (process.send) {
26
+ process.send(message);
27
+ }
28
+ }
29
+ }
30
+ });
31
+ this.childProcess.once('exit', (code, signal) => {
32
+ if (code === null)
33
+ code = (0, exit_codes_1.signalToCode)(signal);
34
+ for (const cb of this.exitCallbacks) {
35
+ cb(code);
36
+ }
37
+ });
38
+ }
39
+ onExit(cb) {
40
+ this.exitCallbacks.push(cb);
41
+ }
42
+ onResults(cb) {
43
+ this.resultsCallbacks.push(cb);
44
+ }
45
+ async getResults() {
46
+ return Promise.race([
47
+ new Promise((_, rej) => {
48
+ this.onExit((code) => {
49
+ if (code !== 0) {
50
+ rej(new Error(`"${this.executorName}" exited unexpectedly with code: ${code}`));
51
+ }
52
+ });
53
+ }),
54
+ new Promise((res) => {
55
+ this.onResults(res);
56
+ }),
57
+ ]);
58
+ }
59
+ send(message) {
60
+ if (this.childProcess.connected) {
61
+ this.childProcess.send(message);
62
+ }
63
+ }
64
+ kill(signal) {
65
+ if (this.childProcess.connected) {
66
+ this.childProcess.kill(signal);
67
+ }
68
+ }
69
+ }
70
+ exports.BatchProcess = BatchProcess;
@@ -0,0 +1,36 @@
1
+ import { ChildProcess, Serializable } from 'child_process';
2
+ import { RunningTask } from './running-task';
3
+ export declare class NodeChildProcessWithNonDirectOutput implements RunningTask {
4
+ private childProcess;
5
+ private terminalOutput;
6
+ private exitCallbacks;
7
+ constructor(childProcess: ChildProcess, { streamOutput, prefix }: {
8
+ streamOutput: boolean;
9
+ prefix: string;
10
+ });
11
+ onExit(cb: (code: number, terminalOutput: string) => void): void;
12
+ getResults(): Promise<{
13
+ code: number;
14
+ terminalOutput: string;
15
+ }>;
16
+ send(message: Serializable): void;
17
+ kill(signal?: NodeJS.Signals | number): void;
18
+ }
19
+ export declare class NodeChildProcessWithDirectOutput implements RunningTask {
20
+ private childProcess;
21
+ private temporaryOutputPath;
22
+ private terminalOutput;
23
+ private exitCallbacks;
24
+ private exited;
25
+ private exitCode;
26
+ constructor(childProcess: ChildProcess, temporaryOutputPath: string);
27
+ send(message: Serializable): void;
28
+ onExit(cb: (code: number, signal: NodeJS.Signals) => void): void;
29
+ getResults(): Promise<{
30
+ code: number;
31
+ terminalOutput: string;
32
+ }>;
33
+ waitForExit(): Promise<void>;
34
+ getTerminalOutput(): string;
35
+ kill(signal?: NodeJS.Signals | number): void;
36
+ }