Skip to content

Commit 08ab57a

Browse files
committed
chore(core): add perf logging
1 parent 4e7f5ab commit 08ab57a

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
@@ -119,6 +119,8 @@ export class DbCache {
119119
}
120120

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

124126
if (this.shouldDelegateToDaemon()) {
@@ -127,6 +129,13 @@ export class DbCache {
127129
res = this.cache.get(task.hash);
128130
}
129131

132+
performance.mark('db:cache.get:end');
133+
performance.measure(
134+
'db:cache.get',
135+
'db:cache.get:start',
136+
'db:cache.get:end'
137+
);
138+
130139
if (res) {
131140
return {
132141
...res,
@@ -156,10 +165,28 @@ export class DbCache {
156165
}
157166

158167
getUsedCacheSpace(): number | Promise<number> {
168+
performance.mark('db:cache.getUsedCacheSpace:start');
169+
159170
if (this.shouldDelegateToDaemon()) {
160-
return daemonClient.cacheGetSize();
171+
return daemonClient.cacheGetSize().then((size) => {
172+
performance.mark('db:cache.getUsedCacheSpace:end');
173+
performance.measure(
174+
'db:cache.getUsedCacheSpace',
175+
'db:cache.getUsedCacheSpace:start',
176+
'db:cache.getUsedCacheSpace:end'
177+
);
178+
return size;
179+
});
161180
}
162-
return this.cache.getCacheSize();
181+
182+
const result = this.cache.getCacheSize();
183+
performance.mark('db:cache.getUsedCacheSpace:end');
184+
performance.measure(
185+
'db:cache.getUsedCacheSpace',
186+
'db:cache.getUsedCacheSpace:start',
187+
'db:cache.getUsedCacheSpace:end'
188+
);
189+
return result;
163190
}
164191

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

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

201237
removeOldCacheRecords(): void | Promise<void> {
238+
performance.mark('db:cache.removeOldRecords:start');
239+
202240
if (this.shouldDelegateToDaemon()) {
203-
return daemonClient.cacheRemoveOldRecords();
241+
return daemonClient.cacheRemoveOldRecords().then((result) => {
242+
performance.mark('db:cache.removeOldRecords:end');
243+
performance.measure(
244+
'db:cache.removeOldRecords',
245+
'db:cache.removeOldRecords:start',
246+
'db:cache.removeOldRecords:end'
247+
);
248+
return result;
249+
});
204250
}
205-
return this.cache.removeOldCacheRecords();
251+
252+
const result = this.cache.removeOldCacheRecords();
253+
performance.mark('db:cache.removeOldRecords:end');
254+
performance.measure(
255+
'db:cache.removeOldRecords',
256+
'db:cache.removeOldRecords:start',
257+
'db:cache.removeOldRecords:end'
258+
);
259+
return result;
206260
}
207261

208262
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)