From 26ea33f8c89bf02eab3937399fae28dd0b796b3a Mon Sep 17 00:00:00 2001 From: fullex <0xfullex@gmail.com> Date: Tue, 6 Jan 2026 10:01:04 +0800 Subject: [PATCH] refactor(CacheService): change hook tracking from Set to Map for reference counting - Updated the CacheService to replace the Set used for active hook tracking with a Map to maintain reference counts for each hook. - Modified methods for registering and unregistering hooks to increment and decrement counts accordingly. - Adjusted internal deletion checks to utilize the new reference counting mechanism. - Updated mock implementations in tests to reflect the changes in hook tracking. This refactor enhances the management of hook references, allowing for more precise control over hook usage and deletion. --- src/renderer/src/data/CacheService.ts | 25 ++++++++++++++------ tests/__mocks__/renderer/CacheService.ts | 29 ++++++++++++++++-------- 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/src/renderer/src/data/CacheService.ts b/src/renderer/src/data/CacheService.ts index f88432ee10..b3324415a1 100644 --- a/src/renderer/src/data/CacheService.ts +++ b/src/renderer/src/data/CacheService.ts @@ -56,8 +56,8 @@ export class CacheService { private sharedCache = new Map() // Cross-window cache (local copy) private persistCache = new Map() // Persistent cache - // Hook reference tracking - private activeHooks = new Set() + // Hook reference tracking (reference-counted) + private activeHookCounts = new Map() // Subscription management private subscribers = new Map>() @@ -346,7 +346,7 @@ export class CacheService { */ private deleteInternal(key: string): boolean { // Check if key is being used by hooks - if (this.activeHooks.has(key)) { + if (this.activeHookCounts.get(key)) { logger.error(`Cannot delete key "${key}" as it's being used by useCache hook`) return false } @@ -574,7 +574,7 @@ export class CacheService { */ private deleteSharedInternal(key: string): boolean { // Check if key is being used by hooks - if (this.activeHooks.has(key)) { + if (this.activeHookCounts.get(key)) { logger.error(`Cannot delete key "${key}" as it's being used by useSharedCache hook`) return false } @@ -666,7 +666,8 @@ export class CacheService { * @param key - Cache key being used by the hook */ registerHook(key: string): void { - this.activeHooks.add(key) + const currentCount = this.activeHookCounts.get(key) ?? 0 + this.activeHookCounts.set(key, currentCount + 1) } /** @@ -674,7 +675,17 @@ export class CacheService { * @param key - Cache key no longer being used by the hook */ unregisterHook(key: string): void { - this.activeHooks.delete(key) + const currentCount = this.activeHookCounts.get(key) + if (!currentCount) { + return + } + + if (currentCount === 1) { + this.activeHookCounts.delete(key) + return + } + + this.activeHookCounts.set(key, currentCount - 1) } // ============ Shared Cache Ready State Management ============ @@ -998,7 +1009,7 @@ export class CacheService { this.persistCache.clear() // Clear tracking - this.activeHooks.clear() + this.activeHookCounts.clear() this.subscribers.clear() logger.debug('CacheService cleanup completed') diff --git a/tests/__mocks__/renderer/CacheService.ts b/tests/__mocks__/renderer/CacheService.ts index 69f41f8689..6f8a142f14 100644 --- a/tests/__mocks__/renderer/CacheService.ts +++ b/tests/__mocks__/renderer/CacheService.ts @@ -32,7 +32,7 @@ export const createMockCacheService = ( const persistCache = new Map(options.initialPersistCache || []) // Active hooks tracking - const activeHooks = new Set() + const activeHookCounts = new Map() // Mock subscribers const subscribers = new Map>() @@ -102,7 +102,7 @@ export const createMockCacheService = ( }), delete: vi.fn((key: K): boolean => { - if (activeHooks.has(key)) { + if (activeHookCounts.get(key)) { console.error(`Cannot delete key "${key}" as it's being used by useCache hook`) return false } @@ -157,7 +157,7 @@ export const createMockCacheService = ( }), deleteCasual: vi.fn((key: string): boolean => { - if (activeHooks.has(key)) { + if (activeHookCounts.get(key)) { console.error(`Cannot delete key "${key}" as it's being used by useCache hook`) return false } @@ -212,7 +212,7 @@ export const createMockCacheService = ( }), deleteShared: vi.fn((key: K): boolean => { - if (activeHooks.has(key)) { + if (activeHookCounts.get(key)) { console.error(`Cannot delete key "${key}" as it's being used by useSharedCache hook`) return false } @@ -267,7 +267,7 @@ export const createMockCacheService = ( }), deleteSharedCasual: vi.fn((key: string): boolean => { - if (activeHooks.has(key)) { + if (activeHookCounts.get(key)) { console.error(`Cannot delete key "${key}" as it's being used by useSharedCache hook`) return false } @@ -305,11 +305,20 @@ export const createMockCacheService = ( // ============ Hook Reference Management ============ registerHook: vi.fn((key: string): void => { - activeHooks.add(key) + const currentCount = activeHookCounts.get(key) ?? 0 + activeHookCounts.set(key, currentCount + 1) }), unregisterHook: vi.fn((key: string): void => { - activeHooks.delete(key) + const currentCount = activeHookCounts.get(key) + if (!currentCount) { + return + } + if (currentCount === 1) { + activeHookCounts.delete(key) + return + } + activeHookCounts.set(key, currentCount - 1) }), // ============ Shared Cache Ready State ============ @@ -362,7 +371,7 @@ export const createMockCacheService = ( memoryCache.clear() sharedCache.clear() persistCache.clear() - activeHooks.clear() + activeHookCounts.clear() subscribers.clear() }), @@ -372,7 +381,7 @@ export const createMockCacheService = ( memoryCache: new Map(memoryCache), sharedCache: new Map(sharedCache), persistCache: new Map(persistCache), - activeHooks: new Set(activeHooks), + activeHookCounts: new Map(activeHookCounts), subscribers: new Map(subscribers), sharedCacheReady }), @@ -381,7 +390,7 @@ export const createMockCacheService = ( memoryCache.clear() sharedCache.clear() persistCache.clear() - activeHooks.clear() + activeHookCounts.clear() subscribers.clear() sharedCacheReady = true },