fix: a bare script now exits cleanly after close() — release every process keep-alive
A consumer report on the GA pair: any minimal add/find/close script hangs forever. Root cause was FOUR ref'd keep-alives brainy never released: 1+2. The global SIGTERM/SIGINT shutdown hooks (registered once at init) were anonymous and never removed — a process.on signal listener holds a ref'd signal handle. They are now named statics, deregistered when the LAST live instance closes (Brainy.instances also stopped leaking closed instances); a later init re-registers them. 3. UnifiedCache.startFairnessMonitor() created an interval it never stored, cleared, or unref'd — unclearable by construction. Now stored + unref'd (same posture as the existing memory-pressure timer): a cache monitor must never keep the host process alive. 4. brainy.close() never called VirtualFileSystem.close(), stranding the VFS background-maintenance interval and the PathResolver maintenance interval. close() now shuts the VFS down. Proof: a bare script (init/add/close, no process.exit) exits 1 ms after close() returns; before the fix it hung until killed. 3 new lifecycle tests pin the hook semantics (once globally, survive while other instances live, removed on last close, re-register after).
This commit is contained in:
parent
ef2022ffd3
commit
c540d63b69
3 changed files with 146 additions and 11 deletions
|
|
@ -79,6 +79,7 @@ export class UnifiedCache implements CacheProvider {
|
|||
private readonly memoryInfo: MemoryInfo
|
||||
private readonly allocationStrategy: CacheAllocationStrategy
|
||||
private memoryPressureCheckTimer: NodeJS.Timeout | null = null
|
||||
private fairnessMonitorTimer: NodeJS.Timeout | null = null
|
||||
private lastMemoryWarning = 0
|
||||
|
||||
constructor(config: UnifiedCacheConfig = {}) {
|
||||
|
|
@ -313,12 +314,19 @@ export class UnifiedCache implements CacheProvider {
|
|||
}
|
||||
|
||||
/**
|
||||
* Fairness monitoring - prevent one type from hogging cache
|
||||
* Fairness monitoring - prevent one type from hogging cache.
|
||||
*
|
||||
* The interval is unref'd: a background cache monitor must never keep the
|
||||
* host process alive (this exact timer made bare scripts hang after
|
||||
* `brain.close()` — the loop could not drain while it stayed ref'd).
|
||||
*/
|
||||
private startFairnessMonitor(): void {
|
||||
setInterval(() => {
|
||||
this.fairnessMonitorTimer = setInterval(() => {
|
||||
this.checkFairness()
|
||||
}, this.config.fairnessCheckInterval!)
|
||||
if (this.fairnessMonitorTimer.unref) {
|
||||
this.fairnessMonitorTimer.unref()
|
||||
}
|
||||
}
|
||||
|
||||
private checkFairness(): void {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue