fix(vfs): resolve two critical VFS bugs causing directory listing corruption
Bug 1: verbCountsByType optimization skipping requested verb types - After restart, stale statistics could cause VerbType.Contains to be skipped - readdir() would return empty/incomplete results - Fixed by never skipping verb types explicitly requested in filter - Added fast path for sourceId + verbType combo (common VFS pattern) - Save statistics on first entity of each type (not just every 100th) Bug 2: UnifiedCache not invalidated on path deletion - rmdir() cleared local caches but NOT the global UnifiedCache - When folder recreated, resolve() returned stale entity ID - Caused "Source entity not found" errors - Fixed by adding deleteByPrefix() to UnifiedCache - Fixed invalidatePath() to also clear UnifiedCache entries Files modified: - src/storage/baseStorage.ts (verbCountsByType fix + fast path) - src/utils/unifiedCache.ts (deleteByPrefix method) - src/vfs/PathResolver.ts (cache invalidation fix) Tests added: - tests/unit/storage/vfs-mkdir-bug.test.ts (7 tests) Reported by: Soulcraft Workshop team 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
1da6048245
commit
2ba69eccdc
4 changed files with 375 additions and 13 deletions
|
|
@ -345,30 +345,44 @@ export class PathResolver {
|
|||
|
||||
/**
|
||||
* Invalidate cache entries for a path and its children
|
||||
* v6.2.9 FIX: Also invalidates UnifiedCache to prevent stale entity IDs
|
||||
* This fixes the "Source entity not found" bug after delete+recreate operations
|
||||
*/
|
||||
invalidatePath(path: string, recursive = false): void {
|
||||
const normalizedPath = this.normalizePath(path)
|
||||
|
||||
// Remove from all caches
|
||||
// v6.2.9 FIX: Clear parent cache BEFORE deleting from pathCache
|
||||
// (we need the entityId from the cache entry)
|
||||
const cached = this.pathCache.get(normalizedPath)
|
||||
if (cached) {
|
||||
this.parentCache.delete(cached.entityId)
|
||||
}
|
||||
|
||||
// Remove from local caches
|
||||
this.pathCache.delete(normalizedPath)
|
||||
this.hotPaths.delete(normalizedPath)
|
||||
|
||||
// v6.2.9 CRITICAL FIX: Also invalidate UnifiedCache (global LRU cache)
|
||||
// This was missing before, causing stale entity IDs to be returned after delete
|
||||
const cacheKey = `vfs:path:${normalizedPath}`
|
||||
getGlobalCache().delete(cacheKey)
|
||||
|
||||
if (recursive) {
|
||||
// Remove all paths that start with this path
|
||||
const prefix = normalizedPath.endsWith('/') ? normalizedPath : normalizedPath + '/'
|
||||
|
||||
for (const [cachedPath] of this.pathCache) {
|
||||
for (const [cachedPath, entry] of this.pathCache) {
|
||||
if (cachedPath.startsWith(prefix)) {
|
||||
this.pathCache.delete(cachedPath)
|
||||
this.hotPaths.delete(cachedPath)
|
||||
// v6.2.9: Also clear parent cache for this entry
|
||||
this.parentCache.delete(entry.entityId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clear parent cache for the entity
|
||||
const cached = this.pathCache.get(normalizedPath)
|
||||
if (cached) {
|
||||
this.parentCache.delete(cached.entityId)
|
||||
// v6.2.9 CRITICAL FIX: Also invalidate UnifiedCache entries with this prefix
|
||||
const globalCachePrefix = `vfs:path:${prefix}`
|
||||
getGlobalCache().deleteByPrefix(globalCachePrefix)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue