mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-08 16:39:42 +02:00
perf: add debounced writes to state-store
- Debounce save() calls by 500ms to batch multiple updates - Add saveNow() for immediate persistence when needed - Add flush() method for shutdown cleanup - Reduces disk I/O from O(n) to O(1) for rapid state changes Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
+31
-1
@@ -3,9 +3,14 @@ import { homedir } from 'node:os';
|
|||||||
import { dirname, join } from 'node:path';
|
import { dirname, join } from 'node:path';
|
||||||
import { AppState, createInitialState } from './types.js';
|
import { AppState, createInitialState } from './types.js';
|
||||||
|
|
||||||
|
// Debounce delay for batching state writes (ms)
|
||||||
|
const SAVE_DEBOUNCE_MS = 500;
|
||||||
|
|
||||||
export class StateStore {
|
export class StateStore {
|
||||||
private state: AppState;
|
private state: AppState;
|
||||||
private filePath: string;
|
private filePath: string;
|
||||||
|
private saveTimeout: NodeJS.Timeout | null = null;
|
||||||
|
private dirty: boolean = false;
|
||||||
|
|
||||||
constructor(filePath?: string) {
|
constructor(filePath?: string) {
|
||||||
this.filePath = filePath || join(homedir(), '.claudeman', 'state.json');
|
this.filePath = filePath || join(homedir(), '.claudeman', 'state.json');
|
||||||
@@ -42,11 +47,36 @@ export class StateStore {
|
|||||||
return createInitialState();
|
return createInitialState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Debounced save - batches multiple updates into a single write
|
||||||
save(): void {
|
save(): void {
|
||||||
|
this.dirty = true;
|
||||||
|
if (this.saveTimeout) {
|
||||||
|
return; // Already scheduled
|
||||||
|
}
|
||||||
|
this.saveTimeout = setTimeout(() => {
|
||||||
|
this.saveNow();
|
||||||
|
}, SAVE_DEBOUNCE_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Immediate save - use when you need guaranteed persistence
|
||||||
|
saveNow(): void {
|
||||||
|
if (this.saveTimeout) {
|
||||||
|
clearTimeout(this.saveTimeout);
|
||||||
|
this.saveTimeout = null;
|
||||||
|
}
|
||||||
|
if (!this.dirty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.dirty = false;
|
||||||
this.ensureDir();
|
this.ensureDir();
|
||||||
writeFileSync(this.filePath, JSON.stringify(this.state, null, 2), 'utf-8');
|
writeFileSync(this.filePath, JSON.stringify(this.state, null, 2), 'utf-8');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Flush any pending saves (call before shutdown)
|
||||||
|
flush(): void {
|
||||||
|
this.saveNow();
|
||||||
|
}
|
||||||
|
|
||||||
getState(): AppState {
|
getState(): AppState {
|
||||||
return this.state;
|
return this.state;
|
||||||
}
|
}
|
||||||
@@ -108,7 +138,7 @@ export class StateStore {
|
|||||||
reset(): void {
|
reset(): void {
|
||||||
this.state = createInitialState();
|
this.state = createInitialState();
|
||||||
this.state.config.stateFilePath = this.filePath;
|
this.state.config.stateFilePath = this.filePath;
|
||||||
this.save();
|
this.saveNow(); // Immediate save for reset operations
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user