Skip to content

Commit 00a771d

Browse files
committed
chore(core): add perf logging
1 parent 7c90bc6 commit 00a771d

File tree

5 files changed

+201
-16
lines changed

5 files changed

+201
-16
lines changed

packages/nx/src/hasher/task-details-recorder.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { performance } from 'perf_hooks';
12
import type { HashedTask } from '../native';
23
import { IS_WASM, TaskDetails } from '../native';
34
import { getDbConnection } from '../utils/db-connection';
@@ -17,6 +18,8 @@ class TaskDetailsRecorder {
1718
async recordTaskDetails(tasks: HashedTask[]): Promise<void> {
1819
if (tasks.length === 0) return;
1920

21+
performance.mark('db:taskDetails.record:start');
22+
2023
if (
2124
isOnDaemon() ||
2225
!daemonClient.enabled() ||
@@ -26,6 +29,13 @@ class TaskDetailsRecorder {
2629
} else {
2730
await daemonClient.recordTaskDetails(tasks);
2831
}
32+
33+
performance.mark('db:taskDetails.record:end');
34+
performance.measure(
35+
'db:taskDetails.record',
36+
'db:taskDetails.record:start',
37+
'db:taskDetails.record:end'
38+
);
2939
}
3040
}
3141

packages/nx/src/tasks-runner/cache.ts

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ export class DbCache {
120120
}
121121

122122
async get(task: Task): Promise<CachedResult | null> {
123+
performance.mark('db:cache.get:start');
124+
123125
let res: NativeCacheResult | null;
124126

125127
if (this.shouldDelegateToDaemon()) {
@@ -128,6 +130,13 @@ export class DbCache {
128130
res = this.cache.get(task.hash);
129131
}
130132

133+
performance.mark('db:cache.get:end');
134+
performance.measure(
135+
'db:cache.get',
136+
'db:cache.get:start',
137+
'db:cache.get:end'
138+
);
139+
131140
if (res) {
132141
return {
133142
...res,
@@ -157,10 +166,28 @@ export class DbCache {
157166
}
158167

159168
getUsedCacheSpace(): number | Promise<number> {
169+
performance.mark('db:cache.getUsedCacheSpace:start');
170+
160171
if (this.shouldDelegateToDaemon()) {
161-
return daemonClient.cacheGetSize();
172+
return daemonClient.cacheGetSize().then((size) => {
173+
performance.mark('db:cache.getUsedCacheSpace:end');
174+
performance.measure(
175+
'db:cache.getUsedCacheSpace',
176+
'db:cache.getUsedCacheSpace:start',
177+
'db:cache.getUsedCacheSpace:end'
178+
);
179+
return size;
180+
});
162181
}
163-
return this.cache.getCacheSize();
182+
183+
const result = this.cache.getCacheSize();
184+
performance.mark('db:cache.getUsedCacheSpace:end');
185+
performance.measure(
186+
'db:cache.getUsedCacheSpace',
187+
'db:cache.getUsedCacheSpace:start',
188+
'db:cache.getUsedCacheSpace:end'
189+
);
190+
return result;
164191
}
165192

166193
private applyRemoteCacheResults(
@@ -181,12 +208,21 @@ export class DbCache {
181208
code: number
182209
) {
183210
return tryAndRetry(async () => {
211+
performance.mark('db:cache.put:start');
212+
184213
if (this.shouldDelegateToDaemon()) {
185214
await daemonClient.cachePut(task.hash, terminalOutput, outputs, code);
186215
} else {
187216
this.cache.put(task.hash, terminalOutput, outputs, code);
188217
}
189218

219+
performance.mark('db:cache.put:end');
220+
performance.measure(
221+
'db:cache.put',
222+
'db:cache.put:start',
223+
'db:cache.put:end'
224+
);
225+
190226
if (this.remoteCache) {
191227
await this.remoteCache.store(task.hash, cacheDir, terminalOutput, code);
192228
}
@@ -200,10 +236,28 @@ export class DbCache {
200236
}
201237

202238
removeOldCacheRecords(): void | Promise<void> {
239+
performance.mark('db:cache.removeOldRecords:start');
240+
203241
if (this.shouldDelegateToDaemon()) {
204-
return daemonClient.cacheRemoveOldRecords();
242+
return daemonClient.cacheRemoveOldRecords().then((result) => {
243+
performance.mark('db:cache.removeOldRecords:end');
244+
performance.measure(
245+
'db:cache.removeOldRecords',
246+
'db:cache.removeOldRecords:start',
247+
'db:cache.removeOldRecords:end'
248+
);
249+
return result;
250+
});
205251
}
206-
return this.cache.removeOldCacheRecords();
252+
253+
const result = this.cache.removeOldCacheRecords();
254+
performance.mark('db:cache.removeOldRecords:end');
255+
performance.measure(
256+
'db:cache.removeOldRecords',
257+
'db:cache.removeOldRecords:start',
258+
'db:cache.removeOldRecords:end'
259+
);
260+
return result;
207261
}
208262

209263
temporaryOutputPath(task: Task): string {
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,43 @@
11
import { PerformanceObserver } from 'perf_hooks';
22

33
let initialized = false;
4+
const measurements: Map<string, number[]> = new Map();
45

56
if (process.env.NX_PERF_LOGGING === 'true' && !initialized) {
67
initialized = true;
78

89
const obs = new PerformanceObserver((list) => {
910
for (const entry of list.getEntries()) {
1011
console.log(`Time for '${entry.name}'`, entry.duration);
12+
13+
// Only aggregate DB operations for summary
14+
if (entry.name.startsWith('db:')) {
15+
if (!measurements.has(entry.name)) {
16+
measurements.set(entry.name, []);
17+
}
18+
measurements.get(entry.name)!.push(entry.duration);
19+
}
1120
}
1221
});
1322
obs.observe({ entryTypes: ['measure'] });
23+
24+
process.on('exit', () => {
25+
if (!global.NX_PLUGIN_WORKER && measurements.size > 0) {
26+
console.log('\n=== DB Operations Performance Summary ===');
27+
let totalTime = 0;
28+
29+
for (const [name, durations] of measurements) {
30+
const total = durations.reduce((a, b) => a + b, 0);
31+
totalTime += total;
32+
console.log(
33+
`${name}: count=${durations.length}, total=${total.toFixed(
34+
2
35+
)}ms, avg=${(total / durations.length).toFixed(2)}ms`
36+
);
37+
}
38+
39+
console.log(`\nTotal DB time: ${totalTime.toFixed(2)}ms`);
40+
console.log('==========================================\n');
41+
}
42+
});
1443
}

packages/nx/src/utils/running-tasks.ts

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { performance } from 'perf_hooks';
12
import {
23
IS_WASM,
34
RunningTasksService as NxRunningTasksService,
@@ -17,36 +18,90 @@ export class RunningTasksService {
1718
}
1819

1920
getRunningTasks(ids: string[]): string[] | Promise<string[]> {
21+
performance.mark('db:runningTasks.get:start');
22+
2023
if (
2124
isOnDaemon() ||
2225
!daemonClient.enabled() ||
2326
!shouldDelegateDbToDaemon()
2427
) {
25-
return this.service.getRunningTasks(ids);
28+
const result = this.service.getRunningTasks(ids);
29+
performance.mark('db:runningTasks.get:end');
30+
performance.measure(
31+
'db:runningTasks.get',
32+
'db:runningTasks.get:start',
33+
'db:runningTasks.get:end'
34+
);
35+
return result;
2636
}
27-
return daemonClient.getRunningTasks(ids);
37+
38+
return daemonClient.getRunningTasks(ids).then((result) => {
39+
performance.mark('db:runningTasks.get:end');
40+
performance.measure(
41+
'db:runningTasks.get',
42+
'db:runningTasks.get:start',
43+
'db:runningTasks.get:end'
44+
);
45+
return result;
46+
});
2847
}
2948

3049
addRunningTask(taskId: string): void | Promise<void> {
50+
performance.mark('db:runningTasks.add:start');
51+
3152
if (
3253
isOnDaemon() ||
3354
!daemonClient.enabled() ||
3455
!shouldDelegateDbToDaemon()
3556
) {
36-
return this.service.addRunningTask(taskId);
57+
const result = this.service.addRunningTask(taskId);
58+
performance.mark('db:runningTasks.add:end');
59+
performance.measure(
60+
'db:runningTasks.add',
61+
'db:runningTasks.add:start',
62+
'db:runningTasks.add:end'
63+
);
64+
return result;
3765
}
38-
return daemonClient.addRunningTask(taskId);
66+
67+
return daemonClient.addRunningTask(taskId).then((result) => {
68+
performance.mark('db:runningTasks.add:end');
69+
performance.measure(
70+
'db:runningTasks.add',
71+
'db:runningTasks.add:start',
72+
'db:runningTasks.add:end'
73+
);
74+
return result;
75+
});
3976
}
4077

4178
removeRunningTask(taskId: string): void | Promise<void> {
79+
performance.mark('db:runningTasks.remove:start');
80+
4281
if (
4382
isOnDaemon() ||
4483
!daemonClient.enabled() ||
4584
!shouldDelegateDbToDaemon()
4685
) {
47-
return this.service.removeRunningTask(taskId);
86+
const result = this.service.removeRunningTask(taskId);
87+
performance.mark('db:runningTasks.remove:end');
88+
performance.measure(
89+
'db:runningTasks.remove',
90+
'db:runningTasks.remove:start',
91+
'db:runningTasks.remove:end'
92+
);
93+
return result;
4894
}
49-
return daemonClient.removeRunningTask(taskId);
95+
96+
return daemonClient.removeRunningTask(taskId).then((result) => {
97+
performance.mark('db:runningTasks.remove:end');
98+
performance.measure(
99+
'db:runningTasks.remove',
100+
'db:runningTasks.remove:start',
101+
'db:runningTasks.remove:end'
102+
);
103+
return result;
104+
});
50105
}
51106
}
52107

packages/nx/src/utils/task-history.ts

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { performance } from 'perf_hooks';
12
import { daemonClient } from '../daemon/client/client';
23
import { isOnDaemon } from '../daemon/is-on-daemon';
34
import { IS_WASM, NxTaskHistory, TaskRun, TaskTarget } from '../native';
@@ -21,24 +22,60 @@ export class TaskHistory {
2122
async getEstimatedTaskTimings(
2223
targets: TaskTarget[]
2324
): Promise<Record<string, number>> {
25+
performance.mark('db:taskHistory.getEstimatedTimings:start');
26+
27+
let result: Record<string, number>;
2428
if (isOnDaemon() || !daemonClient.enabled()) {
25-
return this.taskHistory.getEstimatedTaskTimings(targets);
29+
result = this.taskHistory.getEstimatedTaskTimings(targets);
30+
} else {
31+
result = await daemonClient.getEstimatedTaskTimings(targets);
2632
}
27-
return daemonClient.getEstimatedTaskTimings(targets);
33+
34+
performance.mark('db:taskHistory.getEstimatedTimings:end');
35+
performance.measure(
36+
'db:taskHistory.getEstimatedTimings',
37+
'db:taskHistory.getEstimatedTimings:start',
38+
'db:taskHistory.getEstimatedTimings:end'
39+
);
40+
41+
return result;
2842
}
2943

3044
async getFlakyTasks(hashes: string[]) {
45+
performance.mark('db:taskHistory.getFlakyTasks:start');
46+
47+
let result: string[];
3148
if (isOnDaemon() || !daemonClient.enabled()) {
32-
return this.taskHistory.getFlakyTasks(hashes);
49+
result = this.taskHistory.getFlakyTasks(hashes);
50+
} else {
51+
result = await daemonClient.getFlakyTasks(hashes);
3352
}
34-
return daemonClient.getFlakyTasks(hashes);
53+
54+
performance.mark('db:taskHistory.getFlakyTasks:end');
55+
performance.measure(
56+
'db:taskHistory.getFlakyTasks',
57+
'db:taskHistory.getFlakyTasks:start',
58+
'db:taskHistory.getFlakyTasks:end'
59+
);
60+
61+
return result;
3562
}
3663

3764
async recordTaskRuns(taskRuns: TaskRun[]) {
65+
performance.mark('db:taskHistory.recordTaskRuns:start');
66+
3867
if (isOnDaemon() || !daemonClient.enabled()) {
39-
return this.taskHistory.recordTaskRuns(taskRuns);
68+
this.taskHistory.recordTaskRuns(taskRuns);
69+
} else {
70+
await daemonClient.recordTaskRuns(taskRuns);
4071
}
41-
return daemonClient.recordTaskRuns(taskRuns);
72+
73+
performance.mark('db:taskHistory.recordTaskRuns:end');
74+
performance.measure(
75+
'db:taskHistory.recordTaskRuns',
76+
'db:taskHistory.recordTaskRuns:start',
77+
'db:taskHistory.recordTaskRuns:end'
78+
);
4279
}
4380
}
4481

0 commit comments

Comments
 (0)