Skip to content

Commit b618234

Browse files
haraldschillyclaude
andcommitted
project/backend: optimize ProcessStats with singleton pattern
- Add getInstance() static method to ProcessStats class - Convert all ProcessStats instantiations to use singleton - Eliminates duplicate system calls (getconf CLK_TCK, PAGESIZE) - Provides shared process state for better CPU percentage calculations - Reduces memory footprint by reusing single /proc scanner - Remove redundant ProcessStats instance in exec-stream.ts Affected files: - packages/backend/process-stats.ts: Add singleton pattern - packages/project/exec-stream.ts: Use singleton, remove unused instance - packages/backend/execute-code.ts: Use singleton - packages/project/project-info/server.ts: Use singleton 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 9173397 commit b618234

File tree

4 files changed

+12
-6
lines changed

4 files changed

+12
-6
lines changed

src/packages/backend/execute-code.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ function doSpawn(
345345
const pid = child.pid;
346346
const { job_id, job_config } = opts;
347347
if (job_id == null || pid == null || job_config == null) return;
348-
const monitor = new ProcessStats();
348+
const monitor = ProcessStats.getInstance();
349349
await monitor.init();
350350
await delay(1000);
351351
if (callback_done) return;

src/packages/backend/process-stats.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ interface ProcessStatsOpts {
3838
}
3939

4040
export class ProcessStats {
41+
private static instance: ProcessStats;
42+
4143
private readonly testing: boolean;
4244
private readonly procLimit: number;
4345
private readonly dbg: Function;
@@ -51,6 +53,13 @@ export class ProcessStats {
5153
this.init();
5254
}
5355

56+
public static getInstance(opts?: ProcessStatsOpts): ProcessStats {
57+
if (!ProcessStats.instance) {
58+
ProcessStats.instance = new ProcessStats(opts);
59+
}
60+
return ProcessStats.instance;
61+
}
62+
5463
// this grabs some kernel configuration values we need. they won't change
5564
public init = reuseInFlight(async () => {
5665
if (this.ticks == null) {

src/packages/project/exec-stream.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,13 +156,10 @@ async function executeStream(options) {
156156
let stats: ExecuteCodeStats = [];
157157

158158
// Start process stats monitoring if we have a PID
159-
let statsMonitor: ProcessStats | undefined;
160159
if (job.pid != null) {
161160
logger.debug(
162161
`executeStream: starting stats monitoring for PID ${job.pid}`,
163162
);
164-
statsMonitor = new ProcessStats();
165-
await statsMonitor.init();
166163
startStatsMonitoring(job.pid, job.start, stats, stream, () => done);
167164
} else {
168165
logger.debug(`executeStream: no PID available for stats monitoring`);
@@ -268,7 +265,7 @@ async function startStatsMonitoring(
268265
logger.debug(
269266
`startStatsMonitoring: beginning stats monitoring for PID ${pid}`,
270267
);
271-
const monitor = new ProcessStats();
268+
const monitor = ProcessStats.getInstance();
272269
await monitor.init();
273270
await delay(1000); // Initial delay
274271
if (isDone()) {

src/packages/project/project-info/server.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,7 @@ export class ProjectInfoServer extends EventEmitter {
567567
// Initialize tmpfs detection once at startup
568568
this.tmpIsMemoryBased = await isTmpMemoryBased();
569569
this.running = true;
570-
this.processStats = new ProcessStats({
570+
this.processStats = ProcessStats.getInstance({
571571
testing: this.testing,
572572
dbg: this.dbg,
573573
});

0 commit comments

Comments
 (0)