Skip to content

Commit 426518b

Browse files
Code Index (Qdrant) recreate services when change configurations (#5152)
1 parent 9bf31d3 commit 426518b

File tree

2 files changed

+62
-51
lines changed

2 files changed

+62
-51
lines changed

src/services/code-index/__tests__/manager.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ describe("CodeIndexManager - handleExternalSettingsChange regression", () => {
8989
expect(manager.isInitialized).toBe(true)
9090

9191
// Mock the methods that would be called during restart
92-
const stopWatcherSpy = vitest.spyOn(manager, "stopWatcher").mockImplementation(() => {})
92+
const recreateServicesSpy = vitest.spyOn(manager as any, "_recreateServices").mockImplementation(() => {})
9393
const startIndexingSpy = vitest.spyOn(manager, "startIndexing").mockResolvedValue()
9494

9595
// Mock the feature state
@@ -100,7 +100,7 @@ describe("CodeIndexManager - handleExternalSettingsChange regression", () => {
100100

101101
// Verify that the restart sequence was called
102102
expect(mockConfigManager.loadConfiguration).toHaveBeenCalled()
103-
expect(stopWatcherSpy).toHaveBeenCalled()
103+
expect(recreateServicesSpy).toHaveBeenCalled()
104104
expect(startIndexingSpy).toHaveBeenCalled()
105105
})
106106

src/services/code-index/manager.ts

Lines changed: 60 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -123,54 +123,7 @@ export class CodeIndexManager {
123123
const needsServiceRecreation = !this._serviceFactory || requiresRestart
124124

125125
if (needsServiceRecreation) {
126-
// Stop watcher if it exists
127-
if (this._orchestrator) {
128-
this.stopWatcher()
129-
}
130-
131-
// (Re)Initialize service factory
132-
this._serviceFactory = new CodeIndexServiceFactory(
133-
this._configManager,
134-
this.workspacePath,
135-
this._cacheManager,
136-
)
137-
138-
const ignoreInstance = ignore()
139-
const ignorePath = path.join(getWorkspacePath(), ".gitignore")
140-
try {
141-
const content = await fs.readFile(ignorePath, "utf8")
142-
ignoreInstance.add(content)
143-
ignoreInstance.add(".gitignore")
144-
} catch (error) {
145-
// Should never happen: reading file failed even though it exists
146-
console.error("Unexpected error loading .gitignore:", error)
147-
}
148-
149-
// (Re)Create shared service instances
150-
const { embedder, vectorStore, scanner, fileWatcher } = this._serviceFactory.createServices(
151-
this.context,
152-
this._cacheManager,
153-
ignoreInstance,
154-
)
155-
156-
// (Re)Initialize orchestrator
157-
this._orchestrator = new CodeIndexOrchestrator(
158-
this._configManager,
159-
this._stateManager,
160-
this.workspacePath,
161-
this._cacheManager,
162-
vectorStore,
163-
scanner,
164-
fileWatcher,
165-
)
166-
167-
// (Re)Initialize search service
168-
this._searchService = new CodeIndexSearchService(
169-
this._configManager,
170-
this._stateManager,
171-
embedder,
172-
vectorStore,
173-
)
126+
await this._recreateServices()
174127
}
175128

176129
// 5. Handle Indexing Start/Restart
@@ -248,6 +201,61 @@ export class CodeIndexManager {
248201
return this._searchService!.searchIndex(query, directoryPrefix)
249202
}
250203

204+
/**
205+
* Private helper method to recreate services with current configuration.
206+
* Used by both initialize() and handleExternalSettingsChange().
207+
*/
208+
private async _recreateServices(): Promise<void> {
209+
// Stop watcher if it exists
210+
if (this._orchestrator) {
211+
this.stopWatcher()
212+
}
213+
214+
// (Re)Initialize service factory
215+
this._serviceFactory = new CodeIndexServiceFactory(
216+
this._configManager!,
217+
this.workspacePath,
218+
this._cacheManager!,
219+
)
220+
221+
const ignoreInstance = ignore()
222+
const ignorePath = path.join(getWorkspacePath(), ".gitignore")
223+
try {
224+
const content = await fs.readFile(ignorePath, "utf8")
225+
ignoreInstance.add(content)
226+
ignoreInstance.add(".gitignore")
227+
} catch (error) {
228+
// Should never happen: reading file failed even though it exists
229+
console.error("Unexpected error loading .gitignore:", error)
230+
}
231+
232+
// (Re)Create shared service instances
233+
const { embedder, vectorStore, scanner, fileWatcher } = this._serviceFactory.createServices(
234+
this.context,
235+
this._cacheManager!,
236+
ignoreInstance,
237+
)
238+
239+
// (Re)Initialize orchestrator
240+
this._orchestrator = new CodeIndexOrchestrator(
241+
this._configManager!,
242+
this._stateManager,
243+
this.workspacePath,
244+
this._cacheManager!,
245+
vectorStore,
246+
scanner,
247+
fileWatcher,
248+
)
249+
250+
// (Re)Initialize search service
251+
this._searchService = new CodeIndexSearchService(
252+
this._configManager!,
253+
this._stateManager,
254+
embedder,
255+
vectorStore,
256+
)
257+
}
258+
251259
/**
252260
* Handles external settings changes by reloading configuration.
253261
* This method should be called when API provider settings are updated
@@ -263,7 +271,10 @@ export class CodeIndexManager {
263271

264272
// If configuration changes require a restart and the manager is initialized, restart the service
265273
if (requiresRestart && isFeatureEnabled && isFeatureConfigured && this.isInitialized) {
266-
this.stopWatcher()
274+
// Recreate services with new configuration
275+
await this._recreateServices()
276+
277+
// Start indexing with new services
267278
await this.startIndexing()
268279
}
269280
}

0 commit comments

Comments
 (0)