Skip to content

Commit f59fb2b

Browse files
authored
Merge pull request #1863 from ahoppen/index-schedule-progress
Improve logic for build graph generation status
2 parents 14264b7 + 697e65a commit f59fb2b

File tree

3 files changed

+27
-15
lines changed

3 files changed

+27
-15
lines changed

Sources/SemanticIndex/SemanticIndexManager.swift

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -93,16 +93,16 @@ package enum IndexTaskStatus: Comparable {
9393
/// messages to the user, we only show the highest priority task.
9494
package enum IndexProgressStatus: Sendable {
9595
case preparingFileForEditorFunctionality
96-
case generatingBuildGraph
96+
case schedulingIndexing
9797
case indexing(preparationTasks: [BuildTargetIdentifier: IndexTaskStatus], indexTasks: [DocumentURI: IndexTaskStatus])
9898
case upToDate
9999

100100
package func merging(with other: IndexProgressStatus) -> IndexProgressStatus {
101101
switch (self, other) {
102102
case (_, .preparingFileForEditorFunctionality), (.preparingFileForEditorFunctionality, _):
103103
return .preparingFileForEditorFunctionality
104-
case (_, .generatingBuildGraph), (.generatingBuildGraph, _):
105-
return .generatingBuildGraph
104+
case (_, .schedulingIndexing), (.schedulingIndexing, _):
105+
return .schedulingIndexing
106106
case (
107107
.indexing(let selfPreparationTasks, let selfIndexTasks),
108108
.indexing(let otherPreparationTasks, let otherIndexTasks)
@@ -162,9 +162,9 @@ package final actor SemanticIndexManager {
162162

163163
private let testHooks: IndexTestHooks
164164

165-
/// The task to generate the build graph (resolving package dependencies, generating the build description,
166-
/// ...). `nil` if no build graph is currently being generated.
167-
private var generateBuildGraphTask: Task<Void, Never>?
165+
/// The tasks to generate the build graph (resolving package dependencies, generating the build description,
166+
/// ...) and to schedule indexing of modified tasks.
167+
private var scheduleIndexingTasks: [UUID: Task<Void, Never>] = [:]
168168

169169
private let preparationUpToDateTracker = UpToDateTracker<BuildTargetIdentifier>()
170170

@@ -213,8 +213,8 @@ package final actor SemanticIndexManager {
213213
if inProgressPreparationTasks.values.contains(where: { $0.purpose == .forEditorFunctionality }) {
214214
return .preparingFileForEditorFunctionality
215215
}
216-
if generateBuildGraphTask != nil {
217-
return .generatingBuildGraph
216+
if !scheduleIndexingTasks.isEmpty {
217+
return .schedulingIndexing
218218
}
219219
let preparationTasks = inProgressPreparationTasks.mapValues { inProgressTask in
220220
return inProgressTask.task.isExecuting ? IndexTaskStatus.executing : IndexTaskStatus.scheduled
@@ -275,7 +275,8 @@ package final actor SemanticIndexManager {
275275
filesToIndex: [DocumentURI]?,
276276
indexFilesWithUpToDateUnit: Bool
277277
) async {
278-
generateBuildGraphTask = Task(priority: .low) {
278+
let taskId = UUID()
279+
let generateBuildGraphTask = Task(priority: .low) {
279280
await withLoggingSubsystemAndScope(subsystem: indexLoggingSubsystem, scope: "build-graph-generation") {
280281
await testHooks.buildGraphGenerationDidStart?()
281282
await self.buildSystemManager.waitForUpToDateBuildGraph()
@@ -308,9 +309,10 @@ package final actor SemanticIndexManager {
308309
}
309310
}
310311
await scheduleBackgroundIndex(files: filesToIndex, indexFilesWithUpToDateUnit: indexFilesWithUpToDateUnit)
311-
generateBuildGraphTask = nil
312+
scheduleIndexingTasks[taskId] = nil
312313
}
313314
}
315+
scheduleIndexingTasks[taskId] = generateBuildGraphTask
314316
indexProgressStatusDidChange()
315317
}
316318

@@ -322,12 +324,22 @@ package final actor SemanticIndexManager {
322324
await scheduleBuildGraphGenerationAndBackgroundIndexAllFiles(filesToIndex: nil, indexFilesWithUpToDateUnit: true)
323325
}
324326

327+
private func waitForBuildGraphGenerationTasks() async {
328+
await withTaskGroup(of: Void.self) { taskGroup in
329+
for generateBuildGraphTask in scheduleIndexingTasks.values {
330+
taskGroup.addTask {
331+
await generateBuildGraphTask.value
332+
}
333+
}
334+
}
335+
}
336+
325337
/// Wait for all in-progress index tasks to finish.
326338
package func waitForUpToDateIndex() async {
327339
logger.info("Waiting for up-to-date index")
328340
// Wait for a build graph update first, if one is in progress. This will add all index tasks to `indexStatus`, so we
329341
// can await the index tasks below.
330-
await generateBuildGraphTask?.value
342+
await waitForBuildGraphGenerationTasks()
331343

332344
await withTaskGroup(of: Void.self) { taskGroup in
333345
for (_, status) in inProgressIndexTasks {
@@ -356,7 +368,7 @@ package final actor SemanticIndexManager {
356368
)
357369
// If there's a build graph update in progress wait for that to finish so we can discover new files in the build
358370
// system.
359-
await generateBuildGraphTask?.value
371+
await waitForBuildGraphGenerationTasks()
360372

361373
// Create a new index task for the files that aren't up-to-date. The newly scheduled index tasks will
362374
// - Wait for the existing index operations to finish if they have the same number of files.

Sources/SourceKitLSP/IndexProgressManager.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ actor IndexProgressManager {
9393
case .preparingFileForEditorFunctionality:
9494
message = "Preparing current file"
9595
percentage = 0
96-
case .generatingBuildGraph:
97-
message = "Generating build graph"
96+
case .schedulingIndexing:
97+
message = "Scheduling tasks"
9898
percentage = 0
9999
case .indexing(preparationTasks: let preparationTasks, indexTasks: let indexTasks):
100100
// We can get into a situation where queuedIndexTasks < indexTasks.count if we haven't processed all

Tests/SourceKitLSPTests/BackgroundIndexingTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ final class BackgroundIndexingTests: XCTestCase {
378378
XCTFail("Expected begin notification")
379379
return
380380
}
381-
XCTAssertEqual(beginData.message, "Generating build graph")
381+
XCTAssertEqual(beginData.message, "Scheduling tasks")
382382
let indexingWorkDoneProgressToken = beginNotification.token
383383

384384
_ = try await project.testClient.nextNotification(

0 commit comments

Comments
 (0)