nx 22.1.0-canary.20251029-4a07faf → 22.1.0-canary.20251106-e9146c7
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/executors.json +16 -16
- package/generators.json +13 -13
- package/migrations.json +143 -137
- package/package.json +11 -14
- package/presets/npm.json +4 -4
- package/schemas/nx-schema.json +1286 -1286
- package/schemas/project-schema.json +359 -359
- package/schemas/workspace-schema.json +165 -165
- package/src/ai/set-up-ai-agents/get-agent-rules.d.ts.map +1 -1
- package/src/ai/set-up-ai-agents/get-agent-rules.js +0 -11
- package/src/ai/set-up-ai-agents/schema.json +31 -31
- package/src/command-line/init/implementation/dot-nx/add-nx-scripts.d.ts +2 -0
- package/src/command-line/init/implementation/dot-nx/add-nx-scripts.d.ts.map +1 -1
- package/src/command-line/init/implementation/dot-nx/add-nx-scripts.js +11 -1
- package/src/config/nx-json.d.ts.map +1 -1
- package/src/config/nx-json.js +2 -1
- package/src/core/graph/main.js +1 -1
- package/src/daemon/client/client.d.ts +1 -0
- package/src/daemon/client/client.d.ts.map +1 -1
- package/src/daemon/client/client.js +18 -1
- package/src/devkit-internals.d.ts +1 -1
- package/src/devkit-internals.d.ts.map +1 -1
- package/src/devkit-internals.js +2 -1
- package/src/executors/noop/schema.json +8 -8
- package/src/executors/run-commands/run-commands.impl.d.ts +1 -1
- package/src/executors/run-commands/run-commands.impl.d.ts.map +1 -1
- package/src/executors/run-commands/run-commands.impl.js +7 -4
- package/src/executors/run-commands/running-tasks.d.ts +4 -3
- package/src/executors/run-commands/running-tasks.d.ts.map +1 -1
- package/src/executors/run-commands/running-tasks.js +30 -9
- package/src/executors/run-commands/schema.json +187 -187
- package/src/executors/run-script/schema.json +25 -25
- package/src/generators/internal-utils/format-changed-files-with-prettier-if-available.d.ts.map +1 -1
- package/src/generators/internal-utils/format-changed-files-with-prettier-if-available.js +5 -1
- package/src/hasher/hash-task.d.ts +1 -0
- package/src/hasher/hash-task.d.ts.map +1 -1
- package/src/hasher/hash-task.js +57 -0
- package/src/migrations/update-22-1-0/update-nx-wrapper.d.ts +3 -0
- package/src/migrations/update-22-1-0/update-nx-wrapper.d.ts.map +1 -0
- package/src/migrations/update-22-1-0/update-nx-wrapper.js +7 -0
- package/src/native/index.d.ts +90 -0
- package/src/native/native-bindings.js +1 -0
- package/src/native/nx.wasm32-wasi.wasm +0 -0
- package/src/nx-cloud/generators/connect-to-nx-cloud/schema.json +38 -38
- package/src/project-graph/plugins/isolation/plugin-pool.d.ts.map +1 -1
- package/src/project-graph/plugins/isolation/plugin-pool.js +17 -1
- package/src/tasks-runner/create-task-graph.d.ts.map +1 -1
- package/src/tasks-runner/create-task-graph.js +4 -11
- package/src/tasks-runner/forked-process-task-runner.d.ts.map +1 -1
- package/src/tasks-runner/forked-process-task-runner.js +36 -4
- package/src/tasks-runner/is-tui-enabled.d.ts.map +1 -1
- package/src/tasks-runner/is-tui-enabled.js +0 -4
- package/src/tasks-runner/process-metrics-service.d.ts +54 -0
- package/src/tasks-runner/process-metrics-service.d.ts.map +1 -0
- package/src/tasks-runner/process-metrics-service.js +161 -0
- package/src/tasks-runner/pseudo-terminal.d.ts +1 -0
- package/src/tasks-runner/pseudo-terminal.d.ts.map +1 -1
- package/src/tasks-runner/pseudo-terminal.js +3 -0
- package/src/tasks-runner/running-tasks/node-child-process.d.ts.map +1 -1
- package/src/tasks-runner/task-orchestrator.d.ts.map +1 -1
- package/src/tasks-runner/task-orchestrator.js +3 -7
- package/src/tasks-runner/utils.d.ts +1 -0
- package/src/tasks-runner/utils.d.ts.map +1 -1
- package/src/tasks-runner/utils.js +8 -0
- package/src/utils/update-nxw.d.ts.map +1 -1
- package/src/utils/update-nxw.js +11 -0
package/src/native/index.d.ts
CHANGED
|
@@ -27,6 +27,7 @@ export declare class AppLifeCycle {
|
|
|
27
27
|
|
|
28
28
|
export declare class ChildProcess {
|
|
29
29
|
getParserAndWriter(): ExternalObject<[ParserArc, WriterArc]>
|
|
30
|
+
getPid(): number
|
|
30
31
|
kill(signal?: NodeJS.Signals): void
|
|
31
32
|
onExit(callback: (message: string) => void): void
|
|
32
33
|
onOutput(callback: (message: string) => void): void
|
|
@@ -92,6 +93,45 @@ export declare class NxTaskHistory {
|
|
|
92
93
|
getEstimatedTaskTimings(targets: Array<TaskTarget>): Record<string, number>
|
|
93
94
|
}
|
|
94
95
|
|
|
96
|
+
/**
|
|
97
|
+
* High-performance metrics collector for Nx tasks
|
|
98
|
+
* Thread-safe and designed for minimal overhead
|
|
99
|
+
*/
|
|
100
|
+
export declare class ProcessMetricsCollector {
|
|
101
|
+
/** Create a new ProcessMetricsCollector with default configuration */
|
|
102
|
+
constructor()
|
|
103
|
+
/**
|
|
104
|
+
* Start metrics collection
|
|
105
|
+
* Idempotent - safe to call multiple times
|
|
106
|
+
*/
|
|
107
|
+
startCollection(): void
|
|
108
|
+
/**
|
|
109
|
+
* Stop metrics collection
|
|
110
|
+
* Returns true if collection was stopped, false if not running
|
|
111
|
+
*/
|
|
112
|
+
stopCollection(): boolean
|
|
113
|
+
/**
|
|
114
|
+
* Get system information (CPU cores and total memory)
|
|
115
|
+
* This is separate from the collection interval and meant to be called imperatively
|
|
116
|
+
*/
|
|
117
|
+
getSystemInfo(): SystemInfo
|
|
118
|
+
/** Register the main CLI process for metrics collection */
|
|
119
|
+
registerMainCliProcess(pid: number): void
|
|
120
|
+
/** Register the daemon process for metrics collection */
|
|
121
|
+
registerDaemonProcess(pid: number): void
|
|
122
|
+
/**
|
|
123
|
+
* Register a process for a specific task
|
|
124
|
+
* Automatically creates the task if it doesn't exist
|
|
125
|
+
*/
|
|
126
|
+
registerTaskProcess(taskId: string, pid: number): void
|
|
127
|
+
/** Register a batch with multiple tasks sharing a worker */
|
|
128
|
+
registerBatch(batchId: string, taskIds: Array<string>, pid: number): void
|
|
129
|
+
/** Register a subprocess of the main CLI for metrics collection */
|
|
130
|
+
registerMainCliSubprocess(pid: number): void
|
|
131
|
+
/** Subscribe to push-based metrics notifications from TypeScript */
|
|
132
|
+
subscribe(callback: (err: Error | null, event: MetricsUpdate) => void): void
|
|
133
|
+
}
|
|
134
|
+
|
|
95
135
|
export declare class RunningTasksService {
|
|
96
136
|
constructor(db: ExternalObject<NxDbConnection>)
|
|
97
137
|
getRunningTasks(ids: Array<string>): Array<string>
|
|
@@ -153,6 +193,13 @@ export declare class WorkspaceContext {
|
|
|
153
193
|
getFilesInDirectory(directory: string): Array<string>
|
|
154
194
|
}
|
|
155
195
|
|
|
196
|
+
/** Batch metrics snapshot */
|
|
197
|
+
export interface BatchMetricsSnapshot {
|
|
198
|
+
batchId: string
|
|
199
|
+
taskIds: Array<string>
|
|
200
|
+
processes: Array<ProcessMetrics>
|
|
201
|
+
}
|
|
202
|
+
|
|
156
203
|
export interface CachedResult {
|
|
157
204
|
code: number
|
|
158
205
|
terminalOutput?: string
|
|
@@ -264,6 +311,12 @@ export declare export declare function isEditorInstalled(editor: SupportedEditor
|
|
|
264
311
|
|
|
265
312
|
export declare export declare function logDebug(message: string): void
|
|
266
313
|
|
|
314
|
+
/** Metrics update sent every collection cycle */
|
|
315
|
+
export interface MetricsUpdate {
|
|
316
|
+
metrics: ProcessMetricsSnapshot
|
|
317
|
+
metadata?: Record<string, ProcessMetadata>
|
|
318
|
+
}
|
|
319
|
+
|
|
267
320
|
/** Stripped version of the NxJson interface for use in rust */
|
|
268
321
|
export interface NxJson {
|
|
269
322
|
namedInputs?: Record<string, Array<JsInputs>>
|
|
@@ -283,6 +336,37 @@ export interface NxWorkspaceFilesExternals {
|
|
|
283
336
|
|
|
284
337
|
export declare export declare function parseTaskStatus(stringStatus: string): TaskStatus
|
|
285
338
|
|
|
339
|
+
/** Process metadata (static, doesn't change during process lifetime) */
|
|
340
|
+
export interface ProcessMetadata {
|
|
341
|
+
ppid: number
|
|
342
|
+
name: string
|
|
343
|
+
command: string
|
|
344
|
+
exePath: string
|
|
345
|
+
cwd: string
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/** Process metrics (dynamic, changes every collection) */
|
|
349
|
+
export interface ProcessMetrics {
|
|
350
|
+
pid: number
|
|
351
|
+
cpu: number
|
|
352
|
+
memory: number
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/** Organized collection of process metrics with timestamp */
|
|
356
|
+
export interface ProcessMetricsSnapshot {
|
|
357
|
+
timestamp: number
|
|
358
|
+
mainCli?: ProcessTreeMetrics
|
|
359
|
+
daemon?: ProcessTreeMetrics
|
|
360
|
+
tasks: Record<string, Array<ProcessMetrics>>
|
|
361
|
+
batches: Record<string, BatchMetricsSnapshot>
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/** Metrics for a process and its subprocesses (used for both CLI and daemon) */
|
|
365
|
+
export interface ProcessTreeMetrics {
|
|
366
|
+
main: ProcessMetrics
|
|
367
|
+
subprocesses: Array<ProcessMetrics>
|
|
368
|
+
}
|
|
369
|
+
|
|
286
370
|
export interface Project {
|
|
287
371
|
root: string
|
|
288
372
|
namedInputs?: Record<string, Array<JsInputs>>
|
|
@@ -318,6 +402,12 @@ export declare const enum SupportedEditor {
|
|
|
318
402
|
Unknown = 5
|
|
319
403
|
}
|
|
320
404
|
|
|
405
|
+
/** System information (static system-level data) */
|
|
406
|
+
export interface SystemInfo {
|
|
407
|
+
cpuCores: number
|
|
408
|
+
totalMemory: number
|
|
409
|
+
}
|
|
410
|
+
|
|
321
411
|
export interface Target {
|
|
322
412
|
executor?: string
|
|
323
413
|
inputs?: Array<JsInputs>
|
|
@@ -371,6 +371,7 @@ module.exports.ImportResult = nativeBinding.ImportResult
|
|
|
371
371
|
module.exports.NxCache = nativeBinding.NxCache
|
|
372
372
|
module.exports.NxConsolePreferences = nativeBinding.NxConsolePreferences
|
|
373
373
|
module.exports.NxTaskHistory = nativeBinding.NxTaskHistory
|
|
374
|
+
module.exports.ProcessMetricsCollector = nativeBinding.ProcessMetricsCollector
|
|
374
375
|
module.exports.RunningTasksService = nativeBinding.RunningTasksService
|
|
375
376
|
module.exports.RustPseudoTerminal = nativeBinding.RustPseudoTerminal
|
|
376
377
|
module.exports.TaskDetails = nativeBinding.TaskDetails
|
|
Binary file
|
|
@@ -1,41 +1,41 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
2
|
+
"$schema": "https://json-schema.org/schema",
|
|
3
|
+
"id": "NxCloudInit",
|
|
4
|
+
"title": "Add Nx Cloud Configuration to the workspace",
|
|
5
|
+
"description": "Connect a workspace to Nx Cloud.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"cli": "nx",
|
|
8
|
+
"properties": {
|
|
9
|
+
"analytics": {
|
|
10
|
+
"type": "boolean",
|
|
11
|
+
"description": "Anonymously store hashed machine ID for task runs",
|
|
12
|
+
"default": false
|
|
13
|
+
},
|
|
14
|
+
"installationSource": {
|
|
15
|
+
"type": "string",
|
|
16
|
+
"description": "Name of Nx Cloud installation invoker (ex. user, add-nx-to-monorepo, create-nx-workspace, nx-upgrade",
|
|
17
|
+
"default": "user"
|
|
18
|
+
},
|
|
19
|
+
"hideFormatLogs": {
|
|
20
|
+
"type": "boolean",
|
|
21
|
+
"description": "Hide formatting logs",
|
|
22
|
+
"x-priority": "internal"
|
|
23
|
+
},
|
|
24
|
+
"generateToken": {
|
|
25
|
+
"type": "boolean",
|
|
26
|
+
"description": "Explicitly asks for a token to be created, do not override existing tokens from Nx Cloud"
|
|
27
|
+
},
|
|
28
|
+
"github": {
|
|
29
|
+
"type": "boolean",
|
|
30
|
+
"description": "If the user will be using GitHub as their git hosting provider",
|
|
31
|
+
"default": false
|
|
32
|
+
},
|
|
33
|
+
"directory": {
|
|
34
|
+
"type": "string",
|
|
35
|
+
"description": "The directory where the workspace is located",
|
|
36
|
+
"x-priority": "internal"
|
|
37
|
+
}
|
|
13
38
|
},
|
|
14
|
-
"
|
|
15
|
-
|
|
16
|
-
"description": "Name of Nx Cloud installation invoker (ex. user, add-nx-to-monorepo, create-nx-workspace, nx-upgrade",
|
|
17
|
-
"default": "user"
|
|
18
|
-
},
|
|
19
|
-
"hideFormatLogs": {
|
|
20
|
-
"type": "boolean",
|
|
21
|
-
"description": "Hide formatting logs",
|
|
22
|
-
"x-priority": "internal"
|
|
23
|
-
},
|
|
24
|
-
"generateToken": {
|
|
25
|
-
"type": "boolean",
|
|
26
|
-
"description": "Explicitly asks for a token to be created, do not override existing tokens from Nx Cloud"
|
|
27
|
-
},
|
|
28
|
-
"github": {
|
|
29
|
-
"type": "boolean",
|
|
30
|
-
"description": "If the user will be using GitHub as their git hosting provider",
|
|
31
|
-
"default": false
|
|
32
|
-
},
|
|
33
|
-
"directory": {
|
|
34
|
-
"type": "string",
|
|
35
|
-
"description": "The directory where the workspace is located",
|
|
36
|
-
"x-priority": "internal"
|
|
37
|
-
}
|
|
38
|
-
},
|
|
39
|
-
"additionalProperties": false,
|
|
40
|
-
"required": []
|
|
39
|
+
"additionalProperties": false,
|
|
40
|
+
"required": []
|
|
41
41
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-pool.d.ts","sourceRoot":"","sources":["../../../../../../../packages/nx/src/project-graph/plugins/isolation/plugin-pool.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAK9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AA8C1D,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,mBAAmB,EAC3B,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"plugin-pool.d.ts","sourceRoot":"","sources":["../../../../../../../packages/nx/src/project-graph/plugins/isolation/plugin-pool.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAK9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AA8C1D,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,mBAAmB,EAC3B,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC,CAgFhD"}
|
|
@@ -33,6 +33,22 @@ async function loadRemoteNxPlugin(plugin, root) {
|
|
|
33
33
|
const moduleName = typeof plugin === 'string' ? plugin : plugin.plugin;
|
|
34
34
|
const { name, pluginPath, shouldRegisterTSTranspiler } = await (0, resolve_plugin_1.resolveNxPlugin)(moduleName, root, (0, installation_directory_1.getNxRequirePaths)(root));
|
|
35
35
|
const { worker, socket } = await startPluginWorker();
|
|
36
|
+
// Register plugin worker as a subprocess of the main CLI
|
|
37
|
+
// This allows metrics collection when the daemon is not used
|
|
38
|
+
if (worker.pid) {
|
|
39
|
+
try {
|
|
40
|
+
const { isDaemonEnabled } = await Promise.resolve().then(() => require('../../../daemon/client/client'));
|
|
41
|
+
// Only register if daemon is not enabled - when daemon is enabled,
|
|
42
|
+
// plugin workers are spawned as children of the daemon and tracked automatically
|
|
43
|
+
if (!isDaemonEnabled()) {
|
|
44
|
+
const { getProcessMetricsService } = await Promise.resolve().then(() => require('../../../tasks-runner/process-metrics-service'));
|
|
45
|
+
getProcessMetricsService().registerMainCliSubprocess(worker.pid);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// Silently ignore - metrics collection is optional
|
|
50
|
+
}
|
|
51
|
+
}
|
|
36
52
|
const pendingPromises = new Map();
|
|
37
53
|
const exitHandler = createWorkerExitHandler(worker, pendingPromises);
|
|
38
54
|
const cleanupFunction = () => {
|
|
@@ -271,7 +287,7 @@ async function startPluginWorker() {
|
|
|
271
287
|
}
|
|
272
288
|
: {}),
|
|
273
289
|
};
|
|
274
|
-
const ipcPath = (0, socket_utils_1.getPluginOsSocketPath)([process.pid, global.nxPluginWorkerCount
|
|
290
|
+
const ipcPath = (0, socket_utils_1.getPluginOsSocketPath)([process.pid, global.nxPluginWorkerCount++, performance.now()].join('-'));
|
|
275
291
|
const worker = (0, child_process_1.spawn)(process.execPath, [
|
|
276
292
|
...(isWorkerTypescript ? ['--require', 'ts-node/register'] : []),
|
|
277
293
|
workerPath,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-task-graph.d.ts","sourceRoot":"","sources":["../../../../../packages/nx/src/tasks-runner/create-task-graph.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"create-task-graph.d.ts","sourceRoot":"","sources":["../../../../../packages/nx/src/tasks-runner/create-task-graph.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAWhF,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAOvE,qBAAa,YAAY;IAQrB,OAAO,CAAC,QAAQ,CAAC,uBAAuB;IACxC,OAAO,CAAC,QAAQ,CAAC,YAAY;IAR/B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAqB;IAC1C,QAAQ,CAAC,KAAK,EAAE;QAAE,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAM;IAC5C,QAAQ,CAAC,YAAY,EAAE;QAAE,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;KAAE,CAAM;IACtD,QAAQ,CAAC,sBAAsB,EAAE;QAAE,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;KAAE,CAAM;IAChE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAW;gBAGvB,uBAAuB,EAAE,kBAAkB,EAC3C,YAAY,EAAE,YAAY;IAY7C,YAAY,CACV,YAAY,EAAE,MAAM,EAAE,EACtB,OAAO,EAAE,MAAM,EAAE,EACjB,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,MAAM,EACjB,uBAAuB,EAAE,OAAO,GAC/B,MAAM,EAAE;IAoFX,WAAW,CACT,IAAI,EAAE,IAAI,EACV,+BAA+B,EAAE,MAAM,EACvC,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,MAAM,GAChB,IAAI;IAkDP,OAAO,CAAC,+BAA+B;IA2BvC,OAAO,CAAC,4BAA4B;IAmDpC,OAAO,CAAC,2BAA2B;IAyFnC,OAAO,CAAC,eAAe;IAOvB,UAAU,CACR,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,uBAAuB,EAChC,MAAM,EAAE,MAAM,EACd,qBAAqB,EAAE,MAAM,GAAG,SAAS,EACzC,SAAS,EAAE,MAAM,GAChB,IAAI;IAyCP,oBAAoB,CAClB,OAAO,EAAE,uBAAuB,EAChC,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,GAAG,SAAS;CASpC;AAED,wBAAgB,eAAe,CAC7B,YAAY,EAAE,YAAY,EAC1B,uBAAuB,EAAE,kBAAkB,EAC3C,YAAY,EAAE,MAAM,EAAE,EACtB,OAAO,EAAE,MAAM,EAAE,EACjB,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,SAAS,EAAE,MAAM,EACjB,uBAAuB,GAAE,OAAe,GACvC,SAAS,CAgBX;AAED,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,cAAc,GAAG,SAAS,GACnC,kBAAkB,CAOpB;AAsBD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE;IAAE,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;CAAE,QAoBvE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE;IAAE,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;CAAE,EACvC,MAAM,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EACpB,IAAI,GAAE,GAAG,CAAC,MAAM,CAAa,GAC5B,MAAM,EAAE,CAkBV"}
|
|
@@ -33,7 +33,7 @@ class ProcessTasks {
|
|
|
33
33
|
const project = this.projectGraph.nodes[projectName];
|
|
34
34
|
if (targets.length === 1 || project.data.targets[target]) {
|
|
35
35
|
const resolvedConfiguration = this.resolveConfiguration(project, target, configuration);
|
|
36
|
-
const id = createTaskId(projectName, target, resolvedConfiguration);
|
|
36
|
+
const id = (0, utils_1.createTaskId)(projectName, target, resolvedConfiguration);
|
|
37
37
|
const task = this.createTask(id, project, target, resolvedConfiguration, overrides);
|
|
38
38
|
this.tasks[task.id] = task;
|
|
39
39
|
this.dependencies[task.id] = [];
|
|
@@ -118,7 +118,7 @@ class ProcessTasks {
|
|
|
118
118
|
const selfProject = this.projectGraph.nodes[projectName];
|
|
119
119
|
if ((0, project_graph_utils_1.projectHasTarget)(selfProject, dependencyConfig.target)) {
|
|
120
120
|
const resolvedConfiguration = this.resolveConfiguration(selfProject, dependencyConfig.target, configuration);
|
|
121
|
-
const selfTaskId = createTaskId(selfProject.name, dependencyConfig.target, resolvedConfiguration);
|
|
121
|
+
const selfTaskId = (0, utils_1.createTaskId)(selfProject.name, dependencyConfig.target, resolvedConfiguration);
|
|
122
122
|
if (!this.tasks[selfTaskId]) {
|
|
123
123
|
const newTask = this.createTask(selfTaskId, selfProject, dependencyConfig.target, resolvedConfiguration, taskOverrides);
|
|
124
124
|
this.tasks[selfTaskId] = newTask;
|
|
@@ -147,7 +147,7 @@ class ProcessTasks {
|
|
|
147
147
|
continue;
|
|
148
148
|
if ((0, project_graph_utils_1.projectHasTarget)(depProject, dependencyConfig.target)) {
|
|
149
149
|
const resolvedConfiguration = this.resolveConfiguration(depProject, dependencyConfig.target, configuration);
|
|
150
|
-
const depTargetId = createTaskId(depProject.name, dependencyConfig.target, resolvedConfiguration);
|
|
150
|
+
const depTargetId = (0, utils_1.createTaskId)(depProject.name, dependencyConfig.target, resolvedConfiguration);
|
|
151
151
|
const depTargetConfiguration = this.projectGraph.nodes[depProject.name].data.targets[dependencyConfig.target];
|
|
152
152
|
if (task.id !== depTargetId) {
|
|
153
153
|
if (depTargetConfiguration.continuous) {
|
|
@@ -167,7 +167,7 @@ class ProcessTasks {
|
|
|
167
167
|
}
|
|
168
168
|
else {
|
|
169
169
|
// Create a dummy task for task.target.project... which simulates if depProject had dependencyConfig.target
|
|
170
|
-
const dummyId = createTaskId(depProject.name, task.target.project +
|
|
170
|
+
const dummyId = (0, utils_1.createTaskId)(depProject.name, task.target.project +
|
|
171
171
|
task.target.target +
|
|
172
172
|
'__' +
|
|
173
173
|
dependencyConfig.target +
|
|
@@ -307,10 +307,3 @@ function createTaskOverrides(dependencyConfig, cliOverrides, sourceTask, project
|
|
|
307
307
|
? { ...optionsToForward, ...cliOverrides }
|
|
308
308
|
: { ...optionsToForward, __overrides_unparsed__: [] };
|
|
309
309
|
}
|
|
310
|
-
function createTaskId(project, target, configuration) {
|
|
311
|
-
let id = `${project}:${target}`;
|
|
312
|
-
if (configuration) {
|
|
313
|
-
id += `:${configuration}`;
|
|
314
|
-
}
|
|
315
|
-
return id;
|
|
316
|
-
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"forked-process-task-runner.d.ts","sourceRoot":"","sources":["../../../../../packages/nx/src/tasks-runner/forked-process-task-runner.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAGnE,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAIzC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAkB,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAKvD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"forked-process-task-runner.d.ts","sourceRoot":"","sources":["../../../../../packages/nx/src/tasks-runner/forked-process-task-runner.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAGnE,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAIzC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAkB,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAKvD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAQ3D,qBAAa,uBAAuB;IAShC,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAT7B,OAAO,SAAgB;IAEvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6C;IACrE,OAAO,CAAC,SAAS,CAAyC;IAC1D,OAAO,CAAC,iBAAiB,CAA2B;IACpD,OAAO,CAAC,eAAe,CAA6B;gBAGjC,OAAO,EAAE,yBAAyB,EAClC,UAAU,EAAE,OAAO;IAGhC,IAAI;IAKG,mBAAmB,CAC9B,EAAE,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,EAAE,KAAK,EAClD,YAAY,EAAE,YAAY,EAC1B,aAAa,EAAE,SAAS,EACxB,GAAG,EAAE,MAAM,CAAC,UAAU,GACrB,OAAO,CAAC,YAAY,CAAC;IAiDjB,qBAAqB;IASf,iBAAiB,CAC5B,IAAI,EAAE,IAAI,EACV,EACE,mBAAmB,EACnB,YAAY,EACZ,UAAU,EACV,SAAS,EACT,GAAG,GACJ,EAAE;QACD,mBAAmB,EAAE,MAAM,CAAC;QAC5B,YAAY,EAAE,OAAO,CAAC;QACtB,UAAU,EAAE,OAAO,CAAC;QACpB,SAAS,EAAE,SAAS,CAAC;QACrB,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;KACxB,GACA,OAAO,CAAC,WAAW,CAAC;IAgBV,WAAW,CACtB,IAAI,EAAE,IAAI,EACV,EACE,mBAAmB,EACnB,YAAY,EACZ,SAAS,EACT,GAAG,EACH,qBAAqB,GACtB,EAAE;QACD,mBAAmB,EAAE,MAAM,CAAC;QAC5B,YAAY,EAAE,OAAO,CAAC;QACtB,UAAU,EAAE,OAAO,CAAC;QACpB,SAAS,EAAE,SAAS,CAAC;QACrB,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;QACvB,qBAAqB,EAAE,OAAO,CAAC;KAChC,GACA,OAAO,CAAC,WAAW,GAAG,gBAAgB,CAAC;YAiC5B,oBAAoB;YAYpB,6BAA6B;IAkE3C,OAAO,CAAC,8BAA8B;IAmEtC,OAAO,CAAC,8BAA8B;IA2EtC,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,OAAO;IAO/B,OAAO,CAAC,0BAA0B;CAwCnC"}
|
|
@@ -13,6 +13,7 @@ const exit_codes_1 = require("../utils/exit-codes");
|
|
|
13
13
|
const node_child_process_1 = require("./running-tasks/node-child-process");
|
|
14
14
|
const batch_process_1 = require("./running-tasks/batch-process");
|
|
15
15
|
const native_1 = require("../native");
|
|
16
|
+
const process_metrics_service_1 = require("./process-metrics-service");
|
|
16
17
|
const forkScript = (0, path_1.join)(__dirname, './fork.js');
|
|
17
18
|
const workerPath = (0, path_1.join)(__dirname, './batch/run-batch.js');
|
|
18
19
|
class ForkedProcessTaskRunner {
|
|
@@ -40,8 +41,17 @@ class ForkedProcessTaskRunner {
|
|
|
40
41
|
}
|
|
41
42
|
const p = (0, child_process_1.fork)(workerPath, {
|
|
42
43
|
stdio: ['inherit', 'inherit', 'inherit', 'ipc'],
|
|
43
|
-
env
|
|
44
|
+
env: {
|
|
45
|
+
...env,
|
|
46
|
+
NX_FORKED_TASK_EXECUTOR: 'true',
|
|
47
|
+
},
|
|
44
48
|
});
|
|
49
|
+
// Register batch worker process with all tasks
|
|
50
|
+
if (p.pid) {
|
|
51
|
+
const batchId = `${executorName}-${p.pid}`;
|
|
52
|
+
const taskIds = Object.keys(batchTaskGraph.tasks);
|
|
53
|
+
(0, process_metrics_service_1.getProcessMetricsService)().registerBatch(batchId, taskIds, p.pid);
|
|
54
|
+
}
|
|
45
55
|
const cp = new batch_process_1.BatchProcess(p, executorName);
|
|
46
56
|
this.processes.add(cp);
|
|
47
57
|
cp.onExit(() => {
|
|
@@ -124,10 +134,18 @@ class ForkedProcessTaskRunner {
|
|
|
124
134
|
const p = await pseudoTerminal.fork(childId, forkScript, {
|
|
125
135
|
cwd: process.cwd(),
|
|
126
136
|
execArgv: process.execArgv,
|
|
127
|
-
jsEnv:
|
|
137
|
+
jsEnv: {
|
|
138
|
+
...env,
|
|
139
|
+
NX_FORKED_TASK_EXECUTOR: 'true',
|
|
140
|
+
},
|
|
128
141
|
quiet: !streamOutput,
|
|
129
142
|
commandLabel: `nx run ${task.id}`,
|
|
130
143
|
});
|
|
144
|
+
// Register forked process for metrics collection
|
|
145
|
+
const pid = p.getPid();
|
|
146
|
+
if (pid) {
|
|
147
|
+
(0, process_metrics_service_1.getProcessMetricsService)().registerTaskProcess(task.id, pid);
|
|
148
|
+
}
|
|
131
149
|
p.send({
|
|
132
150
|
targetDescription: task.target,
|
|
133
151
|
overrides: task.overrides,
|
|
@@ -160,8 +178,15 @@ class ForkedProcessTaskRunner {
|
|
|
160
178
|
}
|
|
161
179
|
const p = (0, child_process_1.fork)(this.cliPath, {
|
|
162
180
|
stdio: ['inherit', 'pipe', 'pipe', 'ipc'],
|
|
163
|
-
env
|
|
181
|
+
env: {
|
|
182
|
+
...env,
|
|
183
|
+
NX_FORKED_TASK_EXECUTOR: 'true',
|
|
184
|
+
},
|
|
164
185
|
});
|
|
186
|
+
// Register forked process for metrics collection
|
|
187
|
+
if (p.pid) {
|
|
188
|
+
(0, process_metrics_service_1.getProcessMetricsService)().registerTaskProcess(task.id, p.pid);
|
|
189
|
+
}
|
|
165
190
|
// Send message to run the executor
|
|
166
191
|
p.send({
|
|
167
192
|
targetDescription: task.target,
|
|
@@ -196,8 +221,15 @@ class ForkedProcessTaskRunner {
|
|
|
196
221
|
}
|
|
197
222
|
const p = (0, child_process_1.fork)(this.cliPath, {
|
|
198
223
|
stdio: ['inherit', 'inherit', 'inherit', 'ipc'],
|
|
199
|
-
env
|
|
224
|
+
env: {
|
|
225
|
+
...env,
|
|
226
|
+
NX_FORKED_TASK_EXECUTOR: 'true',
|
|
227
|
+
},
|
|
200
228
|
});
|
|
229
|
+
// Register forked process for metrics collection
|
|
230
|
+
if (p.pid) {
|
|
231
|
+
(0, process_metrics_service_1.getProcessMetricsService)().registerTaskProcess(task.id, p.pid);
|
|
232
|
+
}
|
|
201
233
|
const cp = new node_child_process_1.NodeChildProcessWithDirectOutput(p, temporaryOutputPath);
|
|
202
234
|
this.processes.add(cp);
|
|
203
235
|
// Send message to run the executor
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"is-tui-enabled.d.ts","sourceRoot":"","sources":["../../../../../packages/nx/src/tasks-runner/is-tui-enabled.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAE7D,OAAO,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAIrD;;GAEG;AACH,wBAAgB,YAAY,YAE3B;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,mBAAmB,EAC3B,MAAM,EAAE,MAAM,EACd,mBAAmB,UAAsD,
|
|
1
|
+
{"version":3,"file":"is-tui-enabled.d.ts","sourceRoot":"","sources":["../../../../../packages/nx/src/tasks-runner/is-tui-enabled.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAE7D,OAAO,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAIrD;;GAEG;AACH,wBAAgB,YAAY,YAE3B;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,mBAAmB,EAC3B,MAAM,EAAE,MAAM,EACd,mBAAmB,UAAsD,WA8D1E"}
|
|
@@ -23,7 +23,6 @@ function isTuiEnabled() {
|
|
|
23
23
|
*/
|
|
24
24
|
function shouldUseTui(nxJson, nxArgs, skipCapabilityCheck = process.env.NX_TUI_SKIP_CAPABILITY_CHECK === 'true') {
|
|
25
25
|
// If the current terminal/environment is not capable of displaying the TUI, we don't run it
|
|
26
|
-
const isWindows = process.platform === 'win32';
|
|
27
26
|
const isCapable = skipCapabilityCheck || (process.stderr.isTTY && isUnicodeSupported());
|
|
28
27
|
if (typeof nxArgs.tui === 'boolean') {
|
|
29
28
|
if (nxArgs.tui && !isCapable) {
|
|
@@ -57,9 +56,6 @@ function shouldUseTui(nxJson, nxArgs, skipCapabilityCheck = process.env.NX_TUI_S
|
|
|
57
56
|
(0, is_ci_1.isCI)() ||
|
|
58
57
|
// Interactive TUI doesn't make sense in an AI agent context
|
|
59
58
|
(0, native_1.isAiAgent)() ||
|
|
60
|
-
// TODO(@JamesHenry): Remove this check once Windows issues are fixed.
|
|
61
|
-
// Windows is not working well right now, temporarily disable it on Windows even if it has been specified as enabled
|
|
62
|
-
isWindows ||
|
|
63
59
|
// WASM needs further testing
|
|
64
60
|
native_1.IS_WASM) {
|
|
65
61
|
return false;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { ProcessMetadata, ProcessMetrics, ProcessTreeMetrics, ProcessMetricsSnapshot, BatchMetricsSnapshot, MetricsUpdate, SystemInfo } from '../native';
|
|
2
|
+
export type { ProcessMetadata, ProcessMetrics, ProcessTreeMetrics, ProcessMetricsSnapshot, BatchMetricsSnapshot, MetricsUpdate, SystemInfo, };
|
|
3
|
+
export type MetricsCallback = (event: MetricsUpdate) => void;
|
|
4
|
+
/**
|
|
5
|
+
* Simplified service providing subscription-based access to Rust metrics collector
|
|
6
|
+
* Manages singleton access pattern for metrics collection during execution of tasks and CLI commands
|
|
7
|
+
* All methods handle errors internally to ensure metrics collection never breaks task execution
|
|
8
|
+
*/
|
|
9
|
+
declare class ProcessMetricsService {
|
|
10
|
+
private collector;
|
|
11
|
+
private cleanupRegistered;
|
|
12
|
+
constructor();
|
|
13
|
+
/**
|
|
14
|
+
* Register signal handlers for graceful shutdown
|
|
15
|
+
* Ensures collection thread is stopped cleanly on Ctrl+C or process termination
|
|
16
|
+
*/
|
|
17
|
+
private registerCleanupHandlers;
|
|
18
|
+
/**
|
|
19
|
+
* Subscribe to push-based metrics notifications
|
|
20
|
+
* Collection starts automatically on first subscription (lazy start)
|
|
21
|
+
*/
|
|
22
|
+
subscribe(callback: MetricsCallback): void;
|
|
23
|
+
/**
|
|
24
|
+
* Register a process for a task - creates anchor for discovery
|
|
25
|
+
* This is the core integration point - called from RunningTask constructors
|
|
26
|
+
*/
|
|
27
|
+
registerTaskProcess(taskId: string, pid: number): void;
|
|
28
|
+
/**
|
|
29
|
+
* Register a batch with multiple tasks sharing a worker
|
|
30
|
+
*/
|
|
31
|
+
registerBatch(batchId: string, taskIds: string[], pid: number): void;
|
|
32
|
+
/**
|
|
33
|
+
* Register the daemon process
|
|
34
|
+
*/
|
|
35
|
+
registerDaemonProcess(pid: number): void;
|
|
36
|
+
/**
|
|
37
|
+
* Register a subprocess of the main CLI (e.g., plugin worker)
|
|
38
|
+
*/
|
|
39
|
+
registerMainCliSubprocess(pid: number): void;
|
|
40
|
+
/**
|
|
41
|
+
* Get system information (CPU cores and total memory)
|
|
42
|
+
*/
|
|
43
|
+
getSystemInfo(): SystemInfo | null;
|
|
44
|
+
/**
|
|
45
|
+
* Stop collection and cleanup
|
|
46
|
+
*/
|
|
47
|
+
shutdown(): void;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Get or create the singleton ProcessMetricsService instance
|
|
51
|
+
* Lazy initialization - service only starts when first accessed
|
|
52
|
+
*/
|
|
53
|
+
export declare function getProcessMetricsService(): ProcessMetricsService;
|
|
54
|
+
//# sourceMappingURL=process-metrics-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-metrics-service.d.ts","sourceRoot":"","sources":["../../../../../packages/nx/src/tasks-runner/process-metrics-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACpB,aAAa,EACb,UAAU,EACX,MAAM,WAAW,CAAC;AAGnB,YAAY,EACV,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACpB,aAAa,EACb,UAAU,GACX,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;AAE7D;;;;GAIG;AACH,cAAM,qBAAqB;IACzB,OAAO,CAAC,SAAS,CAAwC;IACzD,OAAO,CAAC,iBAAiB,CAAS;;IAmBlC;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IAe/B;;;OAGG;IACH,SAAS,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI;IA+B1C;;;OAGG;IACH,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAQtD;;OAEG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAQpE;;OAEG;IACH,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAQxC;;OAEG;IACH,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAQ5C;;OAEG;IACH,aAAa,IAAI,UAAU,GAAG,IAAI;IASlC;;OAEG;IACH,QAAQ,IAAI,IAAI;CAOjB;AAOD;;;GAGG;AACH,wBAAgB,wBAAwB,IAAI,qBAAqB,CAKhE"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getProcessMetricsService = getProcessMetricsService;
|
|
4
|
+
const native_1 = require("../native");
|
|
5
|
+
const cache_1 = require("../daemon/cache");
|
|
6
|
+
/**
|
|
7
|
+
* Simplified service providing subscription-based access to Rust metrics collector
|
|
8
|
+
* Manages singleton access pattern for metrics collection during execution of tasks and CLI commands
|
|
9
|
+
* All methods handle errors internally to ensure metrics collection never breaks task execution
|
|
10
|
+
*/
|
|
11
|
+
class ProcessMetricsService {
|
|
12
|
+
constructor() {
|
|
13
|
+
this.collector = null;
|
|
14
|
+
this.cleanupRegistered = false;
|
|
15
|
+
try {
|
|
16
|
+
this.collector = new native_1.ProcessMetricsCollector();
|
|
17
|
+
// Register main nx process as CLI
|
|
18
|
+
this.collector.registerMainCliProcess(process.pid);
|
|
19
|
+
// Register daemon process if available
|
|
20
|
+
const daemonPid = (0, cache_1.getDaemonProcessIdSync)();
|
|
21
|
+
if (daemonPid) {
|
|
22
|
+
this.collector.registerDaemonProcess(daemonPid);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
// Silent failure - metrics collection is optional and should never break task execution
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Register signal handlers for graceful shutdown
|
|
31
|
+
* Ensures collection thread is stopped cleanly on Ctrl+C or process termination
|
|
32
|
+
*/
|
|
33
|
+
registerCleanupHandlers() {
|
|
34
|
+
const cleanup = () => {
|
|
35
|
+
try {
|
|
36
|
+
this.shutdown();
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
// Silent failure during cleanup
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
// Handle various exit scenarios
|
|
43
|
+
process.on('SIGINT', cleanup);
|
|
44
|
+
process.on('SIGTERM', cleanup);
|
|
45
|
+
process.on('exit', cleanup);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Subscribe to push-based metrics notifications
|
|
49
|
+
* Collection starts automatically on first subscription (lazy start)
|
|
50
|
+
*/
|
|
51
|
+
subscribe(callback) {
|
|
52
|
+
if (!this.collector) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
// Start collection on first subscription (idempotent - safe to call multiple times)
|
|
57
|
+
this.collector.startCollection();
|
|
58
|
+
// Register cleanup handlers on first successful start
|
|
59
|
+
// If startCollection() threw, we never reach this line
|
|
60
|
+
if (!this.cleanupRegistered) {
|
|
61
|
+
this.registerCleanupHandlers();
|
|
62
|
+
this.cleanupRegistered = true;
|
|
63
|
+
}
|
|
64
|
+
// Wrap the user's callback to adapt from error-first pattern (err, data) => void
|
|
65
|
+
// to the simple pattern (event) => void that users expect
|
|
66
|
+
// The Rust side uses CalleeHandled which sends (null, data) on success
|
|
67
|
+
this.collector.subscribe((err, event) => {
|
|
68
|
+
if (err) {
|
|
69
|
+
// Silently ignore errors - metrics collection is optional
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
callback(event);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// Silent failure - metrics collection is optional
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Register a process for a task - creates anchor for discovery
|
|
81
|
+
* This is the core integration point - called from RunningTask constructors
|
|
82
|
+
*/
|
|
83
|
+
registerTaskProcess(taskId, pid) {
|
|
84
|
+
try {
|
|
85
|
+
this.collector?.registerTaskProcess(taskId, pid);
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
// Silent failure - metrics collection is optional
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Register a batch with multiple tasks sharing a worker
|
|
93
|
+
*/
|
|
94
|
+
registerBatch(batchId, taskIds, pid) {
|
|
95
|
+
try {
|
|
96
|
+
this.collector?.registerBatch(batchId, taskIds, pid);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
// Silent failure - metrics collection is optional
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Register the daemon process
|
|
104
|
+
*/
|
|
105
|
+
registerDaemonProcess(pid) {
|
|
106
|
+
try {
|
|
107
|
+
this.collector?.registerDaemonProcess(pid);
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
// Silent failure - metrics collection is optional
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Register a subprocess of the main CLI (e.g., plugin worker)
|
|
115
|
+
*/
|
|
116
|
+
registerMainCliSubprocess(pid) {
|
|
117
|
+
try {
|
|
118
|
+
this.collector?.registerMainCliSubprocess(pid);
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
// Silent failure - metrics collection is optional
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Get system information (CPU cores and total memory)
|
|
126
|
+
*/
|
|
127
|
+
getSystemInfo() {
|
|
128
|
+
try {
|
|
129
|
+
return this.collector?.getSystemInfo();
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
// Silent failure - metrics collection is optional
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Stop collection and cleanup
|
|
138
|
+
*/
|
|
139
|
+
shutdown() {
|
|
140
|
+
try {
|
|
141
|
+
this.collector?.stopCollection();
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
// Silent failure during cleanup
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Singleton instance (lazily initialized)
|
|
150
|
+
*/
|
|
151
|
+
let instance = null;
|
|
152
|
+
/**
|
|
153
|
+
* Get or create the singleton ProcessMetricsService instance
|
|
154
|
+
* Lazy initialization - service only starts when first accessed
|
|
155
|
+
*/
|
|
156
|
+
function getProcessMetricsService() {
|
|
157
|
+
if (!instance) {
|
|
158
|
+
instance = new ProcessMetricsService();
|
|
159
|
+
}
|
|
160
|
+
return instance;
|
|
161
|
+
}
|
|
@@ -44,6 +44,7 @@ export declare class PseudoTtyProcess implements RunningTask {
|
|
|
44
44
|
}>;
|
|
45
45
|
onExit(callback: (code: number) => void): void;
|
|
46
46
|
onOutput(callback: (message: string) => void): void;
|
|
47
|
+
getPid(): number | undefined;
|
|
47
48
|
kill(s?: NodeJS.Signals): void;
|
|
48
49
|
getParserAndWriter(): import("../native").ExternalObject<[ParserArc, WriterArc]>;
|
|
49
50
|
}
|