From 18a79031d0aed7a05b2db54017f507eb731aca7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Catriel=20M=C3=BCller?= Date: Thu, 26 Jun 2025 16:14:56 -0300 Subject: [PATCH 1/2] refactor: recreate the code-index services when the configuration change --- src/services/code-index/manager.ts | 109 ++++++++++++++++------------- 1 file changed, 60 insertions(+), 49 deletions(-) diff --git a/src/services/code-index/manager.ts b/src/services/code-index/manager.ts index 465fa95d0c..735bcee670 100644 --- a/src/services/code-index/manager.ts +++ b/src/services/code-index/manager.ts @@ -123,54 +123,7 @@ export class CodeIndexManager { const needsServiceRecreation = !this._serviceFactory || requiresRestart if (needsServiceRecreation) { - // Stop watcher if it exists - if (this._orchestrator) { - this.stopWatcher() - } - - // (Re)Initialize service factory - this._serviceFactory = new CodeIndexServiceFactory( - this._configManager, - this.workspacePath, - this._cacheManager, - ) - - const ignoreInstance = ignore() - const ignorePath = path.join(getWorkspacePath(), ".gitignore") - try { - const content = await fs.readFile(ignorePath, "utf8") - ignoreInstance.add(content) - ignoreInstance.add(".gitignore") - } catch (error) { - // Should never happen: reading file failed even though it exists - console.error("Unexpected error loading .gitignore:", error) - } - - // (Re)Create shared service instances - const { embedder, vectorStore, scanner, fileWatcher } = this._serviceFactory.createServices( - this.context, - this._cacheManager, - ignoreInstance, - ) - - // (Re)Initialize orchestrator - this._orchestrator = new CodeIndexOrchestrator( - this._configManager, - this._stateManager, - this.workspacePath, - this._cacheManager, - vectorStore, - scanner, - fileWatcher, - ) - - // (Re)Initialize search service - this._searchService = new CodeIndexSearchService( - this._configManager, - this._stateManager, - embedder, - vectorStore, - ) + await this._recreateServices() } // 5. Handle Indexing Start/Restart @@ -248,6 +201,61 @@ export class CodeIndexManager { return this._searchService!.searchIndex(query, directoryPrefix) } + /** + * Private helper method to recreate services with current configuration. + * Used by both initialize() and handleExternalSettingsChange(). + */ + private async _recreateServices(): Promise { + // Stop watcher if it exists + if (this._orchestrator) { + this.stopWatcher() + } + + // (Re)Initialize service factory + this._serviceFactory = new CodeIndexServiceFactory( + this._configManager!, + this.workspacePath, + this._cacheManager!, + ) + + const ignoreInstance = ignore() + const ignorePath = path.join(getWorkspacePath(), ".gitignore") + try { + const content = await fs.readFile(ignorePath, "utf8") + ignoreInstance.add(content) + ignoreInstance.add(".gitignore") + } catch (error) { + // Should never happen: reading file failed even though it exists + console.error("Unexpected error loading .gitignore:", error) + } + + // (Re)Create shared service instances + const { embedder, vectorStore, scanner, fileWatcher } = this._serviceFactory.createServices( + this.context, + this._cacheManager!, + ignoreInstance, + ) + + // (Re)Initialize orchestrator + this._orchestrator = new CodeIndexOrchestrator( + this._configManager!, + this._stateManager, + this.workspacePath, + this._cacheManager!, + vectorStore, + scanner, + fileWatcher, + ) + + // (Re)Initialize search service + this._searchService = new CodeIndexSearchService( + this._configManager!, + this._stateManager, + embedder, + vectorStore, + ) + } + /** * Handles external settings changes by reloading configuration. * This method should be called when API provider settings are updated @@ -263,7 +271,10 @@ export class CodeIndexManager { // If configuration changes require a restart and the manager is initialized, restart the service if (requiresRestart && isFeatureEnabled && isFeatureConfigured && this.isInitialized) { - this.stopWatcher() + // Recreate services with new configuration + await this._recreateServices() + + // Start indexing with new services await this.startIndexing() } } From 48043aa1e09c5c8e493d3cbb4a50e5a4ff03a8da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Catriel=20M=C3=BCller?= Date: Thu, 26 Jun 2025 16:35:30 -0300 Subject: [PATCH 2/2] refactor: Update the CodeIndexmanager test --- src/services/code-index/__tests__/manager.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/services/code-index/__tests__/manager.spec.ts b/src/services/code-index/__tests__/manager.spec.ts index 12583291eb..2aaeb1d374 100644 --- a/src/services/code-index/__tests__/manager.spec.ts +++ b/src/services/code-index/__tests__/manager.spec.ts @@ -89,7 +89,7 @@ describe("CodeIndexManager - handleExternalSettingsChange regression", () => { expect(manager.isInitialized).toBe(true) // Mock the methods that would be called during restart - const stopWatcherSpy = vitest.spyOn(manager, "stopWatcher").mockImplementation(() => {}) + const recreateServicesSpy = vitest.spyOn(manager as any, "_recreateServices").mockImplementation(() => {}) const startIndexingSpy = vitest.spyOn(manager, "startIndexing").mockResolvedValue() // Mock the feature state @@ -100,7 +100,7 @@ describe("CodeIndexManager - handleExternalSettingsChange regression", () => { // Verify that the restart sequence was called expect(mockConfigManager.loadConfiguration).toHaveBeenCalled() - expect(stopWatcherSpy).toHaveBeenCalled() + expect(recreateServicesSpy).toHaveBeenCalled() expect(startIndexingSpy).toHaveBeenCalled() })