Skip to content

Commit bfa08bc

Browse files
authored
Merge pull request #5894 from chezsmithy/feat-refactor-codebaseIndexer-from-core
refactor: ♻️ Refactor CodeBaseIndexer out of core
2 parents 43e98ea + 2a719de commit bfa08bc

File tree

5 files changed

+347
-189
lines changed

5 files changed

+347
-189
lines changed

core/core.ts

Lines changed: 21 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { getAuthUrlForTokenPage } from "./control-plane/auth/index";
1414
import { getControlPlaneEnv } from "./control-plane/env";
1515
import { DevDataSqliteDb } from "./data/devdataSqlite";
1616
import { DataLogger } from "./data/log";
17-
import { CodebaseIndexer, PauseToken } from "./indexing/CodebaseIndexer";
17+
import { CodebaseIndexer } from "./indexing/CodebaseIndexer";
1818
import DocsService from "./indexing/docs/DocsService";
1919
import { countTokens } from "./llm/countTokens";
2020
import Ollama from "./llm/llms/Ollama";
@@ -41,7 +41,6 @@ import {
4141
type ContextItem,
4242
type ContextItemId,
4343
type IDE,
44-
type IndexingProgressUpdate,
4544
} from ".";
4645

4746
import { ConfigYaml } from "@continuedev/config-yaml";
@@ -58,7 +57,6 @@ import { setMdmLicenseKey } from "./control-plane/mdm/mdm";
5857
import { streamDiffLines } from "./edit/streamDiffLines";
5958
import { shouldIgnore } from "./indexing/shouldIgnore";
6059
import { walkDirCache } from "./indexing/walkDir";
61-
import { LLMError } from "./llm";
6260
import { LLMLogger } from "./llm/logger";
6361
import { llmStreamChat } from "./llm/streamChat";
6462
import type { FromCoreProtocol, ToCoreProtocol } from "./protocol";
@@ -67,18 +65,12 @@ import { StreamAbortManager } from "./util/abortManager";
6765

6866
export class Core {
6967
configHandler: ConfigHandler;
70-
codebaseIndexerPromise: Promise<CodebaseIndexer>;
68+
codeBaseIndexer: CodebaseIndexer;
7169
completionProvider: CompletionProvider;
72-
continueServerClientPromise: Promise<ContinueServerClient>;
73-
codebaseIndexingState: IndexingProgressUpdate;
7470
private docsService: DocsService;
7571
private globalContext = new GlobalContext();
7672
llmLogger = new LLMLogger();
7773

78-
private readonly indexingPauseToken = new PauseToken(
79-
this.globalContext.get("indexingPaused") === true,
80-
);
81-
8274
private messageAbortControllers = new Map<string, AbortController>();
8375
private addMessageAbortController(id: string): AbortController {
8476
const controller = new AbortController();
@@ -116,12 +108,6 @@ export class Core {
116108
// Ensure .continue directory is created
117109
migrateV1DevDataFiles();
118110

119-
this.codebaseIndexingState = {
120-
status: "loading",
121-
desc: "loading",
122-
progress: 0,
123-
};
124-
125111
const ideInfoPromise = messenger.request("getIdeInfo", undefined);
126112
const ideSettingsPromise = messenger.request("getIdeSettings", undefined);
127113
const sessionInfoPromise = messenger.request("getControlPlaneSessionInfo", {
@@ -146,6 +132,13 @@ export class Core {
146132
await this.configHandler.reloadConfig();
147133
};
148134

135+
this.codeBaseIndexer = new CodebaseIndexer(
136+
this.configHandler,
137+
this.ide,
138+
this.messenger,
139+
this.globalContext.get("indexingPaused"),
140+
);
141+
149142
this.configHandler.onConfigUpdate(async (result) => {
150143
const serializedResult = await this.configHandler.getSerializedConfig();
151144
this.messenger.send("configUpdate", {
@@ -172,38 +165,17 @@ export class Core {
172165
dataLogger.ideInfoPromise = ideInfoPromise;
173166
dataLogger.ideSettingsPromise = ideSettingsPromise;
174167

175-
// Codebase Indexer and ContinueServerClient depend on IdeSettings
176-
let codebaseIndexerResolve: (_: any) => void | undefined;
177-
this.codebaseIndexerPromise = new Promise(
178-
async (resolve) => (codebaseIndexerResolve = resolve),
179-
);
180-
181-
let continueServerClientResolve: (_: any) => void | undefined;
182-
this.continueServerClientPromise = new Promise(
183-
(resolve) => (continueServerClientResolve = resolve),
184-
);
185-
186168
void ideSettingsPromise.then((ideSettings) => {
187169
const continueServerClient = new ContinueServerClient(
188170
ideSettings.remoteConfigServerUrl,
189171
ideSettings.userToken,
190172
);
191-
continueServerClientResolve(continueServerClient);
192-
193-
codebaseIndexerResolve(
194-
new CodebaseIndexer(
195-
this.configHandler,
196-
this.ide,
197-
this.indexingPauseToken,
198-
continueServerClient,
199-
),
200-
);
201173

202174
// Index on initialization
203175
void this.ide.getWorkspaceDirs().then(async (dirs) => {
204176
// Respect pauseCodebaseIndexOnStart user settings
205177
if (ideSettings.pauseCodebaseIndexOnStart) {
206-
this.indexingPauseToken.paused = true;
178+
this.codeBaseIndexer.paused = true;
207179
void this.messenger.request("indexProgress", {
208180
progress: 0,
209181
desc: "Initial Indexing Skipped",
@@ -212,7 +184,7 @@ export class Core {
212184
return;
213185
}
214186

215-
void this.refreshCodebaseIndex(dirs);
187+
await this.codeBaseIndexer.refreshCodebaseIndex(dirs);
216188
});
217189
});
218190

@@ -557,25 +529,24 @@ export class Core {
557529
}
558530
walkDirCache.invalidate();
559531
if (data?.shouldClearIndexes) {
560-
const codebaseIndexer = await this.codebaseIndexerPromise;
561-
await codebaseIndexer.clearIndexes();
532+
await this.codeBaseIndexer.clearIndexes();
562533
}
563534

564535
const dirs = data?.dirs ?? (await this.ide.getWorkspaceDirs());
565-
await this.refreshCodebaseIndex(dirs);
536+
await this.codeBaseIndexer.refreshCodebaseIndex(dirs);
566537
});
567538
on("index/setPaused", (msg) => {
568539
this.globalContext.update("indexingPaused", msg.data);
569-
this.indexingPauseToken.paused = msg.data;
540+
// Update using the new setter instead of token
541+
this.codeBaseIndexer.paused = msg.data;
570542
});
571543
on("index/indexingProgressBarInitialized", async (msg) => {
572544
// Triggered when progress bar is initialized.
573545
// If a non-default state has been stored, update the indexing display to that state
574-
if (this.codebaseIndexingState.status !== "loading") {
575-
void this.messenger.request(
576-
"indexProgress",
577-
this.codebaseIndexingState,
578-
);
546+
const currentState = this.codeBaseIndexer.currentIndexingState;
547+
548+
if (currentState.status !== "loading") {
549+
void this.messenger.request("indexProgress", currentState);
579550
}
580551
});
581552

@@ -595,7 +566,7 @@ export class Core {
595566
});
596567
const { config } = await this.configHandler.loadConfig();
597568
if (config && !config.disableIndexing) {
598-
await this.refreshCodebaseIndexFiles(toRefresh);
569+
await this.codeBaseIndexer.refreshCodebaseIndexFiles(toRefresh);
599570
}
600571
}
601572
};
@@ -866,7 +837,7 @@ export class Core {
866837
// Reindex the file
867838
const ignore = await shouldIgnore(uri, this.ide);
868839
if (!ignore) {
869-
await this.refreshCodebaseIndexFiles([uri]);
840+
await this.codeBaseIndexer.refreshCodebaseIndexFiles([uri]);
870841
}
871842
}
872843
}
@@ -1037,100 +1008,4 @@ export class Core {
10371008
return [];
10381009
}
10391010
};
1040-
1041-
private indexingCancellationController: AbortController | undefined;
1042-
private async sendIndexingErrorTelemetry(update: IndexingProgressUpdate) {
1043-
console.debug(
1044-
"Indexing failed with error: ",
1045-
update.desc,
1046-
update.debugInfo,
1047-
);
1048-
void Telemetry.capture(
1049-
"indexing_error",
1050-
{
1051-
error: update.desc,
1052-
stack: update.debugInfo,
1053-
},
1054-
false,
1055-
);
1056-
}
1057-
1058-
private async refreshCodebaseIndex(paths: string[]) {
1059-
if (this.indexingCancellationController) {
1060-
this.indexingCancellationController.abort();
1061-
}
1062-
this.indexingCancellationController = new AbortController();
1063-
try {
1064-
for await (const update of (
1065-
await this.codebaseIndexerPromise
1066-
).refreshDirs(paths, this.indexingCancellationController.signal)) {
1067-
let updateToSend = { ...update };
1068-
1069-
void this.messenger.request("indexProgress", updateToSend);
1070-
this.codebaseIndexingState = updateToSend;
1071-
1072-
if (update.status === "failed") {
1073-
void this.sendIndexingErrorTelemetry(update);
1074-
}
1075-
}
1076-
} catch (e: any) {
1077-
console.log(`Failed refreshing codebase index directories : ${e}`);
1078-
this.handleIndexingError(e);
1079-
}
1080-
1081-
this.messenger.send("refreshSubmenuItems", {
1082-
providers: "dependsOnIndexing",
1083-
});
1084-
this.indexingCancellationController = undefined;
1085-
}
1086-
1087-
private async refreshCodebaseIndexFiles(files: string[]) {
1088-
// Can be cancelled by codebase index but not vice versa
1089-
if (
1090-
this.indexingCancellationController &&
1091-
!this.indexingCancellationController.signal.aborted
1092-
) {
1093-
return;
1094-
}
1095-
this.indexingCancellationController = new AbortController();
1096-
try {
1097-
for await (const update of (
1098-
await this.codebaseIndexerPromise
1099-
).refreshFiles(files)) {
1100-
let updateToSend = { ...update };
1101-
1102-
void this.messenger.request("indexProgress", updateToSend);
1103-
this.codebaseIndexingState = updateToSend;
1104-
1105-
if (update.status === "failed") {
1106-
void this.sendIndexingErrorTelemetry(update);
1107-
}
1108-
}
1109-
} catch (e: any) {
1110-
console.log(`Failed refreshing codebase index files : ${e}`);
1111-
this.handleIndexingError(e);
1112-
}
1113-
1114-
this.messenger.send("refreshSubmenuItems", {
1115-
providers: "dependsOnIndexing",
1116-
});
1117-
this.indexingCancellationController = undefined;
1118-
}
1119-
1120-
// private
1121-
handleIndexingError(e: any) {
1122-
if (e instanceof LLMError) {
1123-
// Need to report this specific error to the IDE for special handling
1124-
void this.messenger.request("reportError", e);
1125-
}
1126-
// broadcast indexing error
1127-
let updateToSend: IndexingProgressUpdate = {
1128-
progress: 0,
1129-
status: "failed",
1130-
desc: e.message,
1131-
};
1132-
void this.messenger.request("indexProgress", updateToSend);
1133-
this.codebaseIndexingState = updateToSend;
1134-
void this.sendIndexingErrorTelemetry(updateToSend);
1135-
}
11361011
}

0 commit comments

Comments
 (0)