fix: preserve code index and cache after extension updates

- Enhanced cache manager to better handle cache file loading with improved logging
- Added comprehensive logging throughout the indexing lifecycle for better debugging
- Improved collection detection in QdrantVectorStore to properly reuse existing collections
- Added logging to track when existing collections are found and reused vs created new

This ensures that the code index is preserved across extension updates instead of
starting from scratch each time.

Fixes #7088
This commit is contained in:
Roo Code 2025-08-14 09:41:08 +00:00
parent dcbb7a673f
commit 5222e5e82e
4 changed files with 57 additions and 5 deletions

View file

@ -39,13 +39,27 @@ export class CacheManager implements ICacheManager {
try {
const cacheData = await vscode.workspace.fs.readFile(this.cachePath)
this.fileHashes = JSON.parse(cacheData.toString())
console.log(
`[CacheManager] Successfully loaded cache with ${Object.keys(this.fileHashes).length} file hashes from ${this.cachePath.fsPath}`,
)
} catch (error) {
// Check if the error is because the file doesn't exist (expected on first run)
const isFileNotFound =
error instanceof Error && (error.message.includes("FileNotFound") || error.message.includes("ENOENT"))
if (isFileNotFound) {
console.log(
`[CacheManager] Cache file not found at ${this.cachePath.fsPath}, starting with empty cache (this is normal on first run)`,
)
} else {
console.warn(`[CacheManager] Error loading cache from ${this.cachePath.fsPath}:`, error)
TelemetryService.instance.captureEvent(TelemetryEventName.CODE_INDEX_ERROR, {
error: error instanceof Error ? error.message : String(error),
stack: error instanceof Error ? error.stack : undefined,
location: "initialize",
})
}
this.fileHashes = {}
TelemetryService.instance.captureEvent(TelemetryEventName.CODE_INDEX_ERROR, {
error: error instanceof Error ? error.message : String(error),
stack: error instanceof Error ? error.stack : undefined,
location: "initialize",
})
}
}

View file

@ -117,6 +117,8 @@ export class CodeIndexManager {
* @returns Object indicating if a restart is needed
*/
public async initialize(contextProxy: ContextProxy): Promise<{ requiresRestart: boolean }> {
console.log(`[CodeIndexManager] Initializing for workspace: ${this.workspacePath}`)
// 1. ConfigManager Initialization and Configuration Loading
if (!this._configManager) {
this._configManager = new CodeIndexConfigManager(contextProxy)
@ -126,6 +128,7 @@ export class CodeIndexManager {
// 2. Check if feature is enabled
if (!this.isFeatureEnabled) {
console.log("[CodeIndexManager] Code indexing feature is disabled")
if (this._orchestrator) {
this._orchestrator.stopWatcher()
}
@ -135,21 +138,28 @@ export class CodeIndexManager {
// 3. Check if workspace is available
const workspacePath = getWorkspacePath()
if (!workspacePath) {
console.log("[CodeIndexManager] No workspace folder open")
this._stateManager.setSystemState("Standby", "No workspace folder open")
return { requiresRestart }
}
// 4. CacheManager Initialization
if (!this._cacheManager) {
console.log("[CodeIndexManager] Initializing cache manager")
this._cacheManager = new CacheManager(this.context, this.workspacePath)
await this._cacheManager.initialize()
} else {
console.log("[CodeIndexManager] Cache manager already initialized")
}
// 4. Determine if Core Services Need Recreation
const needsServiceRecreation = !this._serviceFactory || requiresRestart
if (needsServiceRecreation) {
console.log(`[CodeIndexManager] Recreating services (requiresRestart: ${requiresRestart})`)
await this._recreateServices()
} else {
console.log("[CodeIndexManager] Services already exist, no recreation needed")
}
// 5. Handle Indexing Start/Restart
@ -160,7 +170,10 @@ export class CodeIndexManager {
(needsServiceRecreation && (!this._orchestrator || this._orchestrator.state !== "Indexing"))
if (shouldStartOrRestartIndexing) {
console.log("[CodeIndexManager] Starting/restarting indexing process")
this._orchestrator?.startIndexing() // This method is async, but we don't await it here
} else {
console.log(`[CodeIndexManager] No indexing restart needed (current state: ${this._orchestrator?.state})`)
}
return { requiresRestart }

View file

@ -127,7 +127,18 @@ export class CodeIndexOrchestrator {
const collectionCreated = await this.vectorStore.initialize()
if (collectionCreated) {
console.log("[CodeIndexOrchestrator] New collection created, clearing cache file")
await this.cacheManager.clearCacheFile()
} else {
console.log("[CodeIndexOrchestrator] Existing collection found and reused")
// Check if we have cached data
const cachedHashes = this.cacheManager.getAllHashes()
const cachedFileCount = Object.keys(cachedHashes).length
if (cachedFileCount > 0) {
console.log(
`[CodeIndexOrchestrator] Found ${cachedFileCount} files in cache, will skip unchanged files during scan`,
)
}
}
this.stateManager.setSystemState("Indexing", "Services ready. Starting workspace scan...")
@ -164,6 +175,9 @@ export class CodeIndexOrchestrator {
}
const { stats } = result
console.log(
`[CodeIndexOrchestrator] Initial scan completed. Files processed: ${stats.processed}, Files skipped: ${stats.skipped}, Blocks indexed: ${cumulativeBlocksIndexed}`,
)
// Check if any blocks were actually indexed successfully
// If no blocks were indexed but blocks were found, it means all batches failed

View file

@ -147,10 +147,14 @@ export class QdrantVectorStore implements IVectorStore {
async initialize(): Promise<boolean> {
let created = false
try {
console.log(
`[QdrantVectorStore] Initializing collection ${this.collectionName} with vector size ${this.vectorSize}`,
)
const collectionInfo = await this.getCollectionInfo()
if (collectionInfo === null) {
// Collection info not retrieved (assume not found or inaccessible), create it
console.log(`[QdrantVectorStore] Collection ${this.collectionName} not found, creating new collection`)
await this.client.createCollection(this.collectionName, {
vectors: {
size: this.vectorSize,
@ -158,6 +162,7 @@ export class QdrantVectorStore implements IVectorStore {
},
})
created = true
console.log(`[QdrantVectorStore] Successfully created new collection ${this.collectionName}`)
} else {
// Collection exists, check vector size
const vectorsConfig = collectionInfo.config?.params?.vectors
@ -177,9 +182,15 @@ export class QdrantVectorStore implements IVectorStore {
}
if (existingVectorSize === this.vectorSize) {
console.log(
`[QdrantVectorStore] Found existing collection ${this.collectionName} with matching vector size ${existingVectorSize}. Reusing existing collection.`,
)
created = false // Exists and correct
} else {
// Exists but wrong vector size, recreate with enhanced error handling
console.log(
`[QdrantVectorStore] Found existing collection ${this.collectionName} with mismatched vector size (expected: ${this.vectorSize}, found: ${existingVectorSize})`,
)
created = await this._recreateCollectionWithNewDimension(existingVectorSize)
}
}