@@ -93,16 +93,16 @@ package enum IndexTaskStatus: Comparable {
93
93
/// messages to the user, we only show the highest priority task.
94
94
package enum IndexProgressStatus : Sendable {
95
95
case preparingFileForEditorFunctionality
96
- case generatingBuildGraph
96
+ case schedulingIndexing
97
97
case indexing( preparationTasks: [ BuildTargetIdentifier : IndexTaskStatus ] , indexTasks: [ DocumentURI : IndexTaskStatus ] )
98
98
case upToDate
99
99
100
100
package func merging( with other: IndexProgressStatus ) -> IndexProgressStatus {
101
101
switch ( self , other) {
102
102
case ( _, . preparingFileForEditorFunctionality) , ( . preparingFileForEditorFunctionality, _) :
103
103
return . preparingFileForEditorFunctionality
104
- case ( _, . generatingBuildGraph ) , ( . generatingBuildGraph , _) :
105
- return . generatingBuildGraph
104
+ case ( _, . schedulingIndexing ) , ( . schedulingIndexing , _) :
105
+ return . schedulingIndexing
106
106
case (
107
107
. indexing( let selfPreparationTasks, let selfIndexTasks) ,
108
108
. indexing( let otherPreparationTasks, let otherIndexTasks)
@@ -162,9 +162,9 @@ package final actor SemanticIndexManager {
162
162
163
163
private let testHooks : IndexTestHooks
164
164
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 > ] = [ : ]
168
168
169
169
private let preparationUpToDateTracker = UpToDateTracker < BuildTargetIdentifier > ( )
170
170
@@ -213,8 +213,8 @@ package final actor SemanticIndexManager {
213
213
if inProgressPreparationTasks. values. contains ( where: { $0. purpose == . forEditorFunctionality } ) {
214
214
return . preparingFileForEditorFunctionality
215
215
}
216
- if generateBuildGraphTask != nil {
217
- return . generatingBuildGraph
216
+ if !scheduleIndexingTasks . isEmpty {
217
+ return . schedulingIndexing
218
218
}
219
219
let preparationTasks = inProgressPreparationTasks. mapValues { inProgressTask in
220
220
return inProgressTask. task. isExecuting ? IndexTaskStatus . executing : IndexTaskStatus . scheduled
@@ -275,7 +275,8 @@ package final actor SemanticIndexManager {
275
275
filesToIndex: [ DocumentURI ] ? ,
276
276
indexFilesWithUpToDateUnit: Bool
277
277
) async {
278
- generateBuildGraphTask = Task ( priority: . low) {
278
+ let taskId = UUID ( )
279
+ let generateBuildGraphTask = Task ( priority: . low) {
279
280
await withLoggingSubsystemAndScope ( subsystem: indexLoggingSubsystem, scope: " build-graph-generation " ) {
280
281
await testHooks. buildGraphGenerationDidStart ? ( )
281
282
await self . buildSystemManager. waitForUpToDateBuildGraph ( )
@@ -308,9 +309,10 @@ package final actor SemanticIndexManager {
308
309
}
309
310
}
310
311
await scheduleBackgroundIndex ( files: filesToIndex, indexFilesWithUpToDateUnit: indexFilesWithUpToDateUnit)
311
- generateBuildGraphTask = nil
312
+ scheduleIndexingTasks [ taskId ] = nil
312
313
}
313
314
}
315
+ scheduleIndexingTasks [ taskId] = generateBuildGraphTask
314
316
indexProgressStatusDidChange ( )
315
317
}
316
318
@@ -322,12 +324,22 @@ package final actor SemanticIndexManager {
322
324
await scheduleBuildGraphGenerationAndBackgroundIndexAllFiles ( filesToIndex: nil , indexFilesWithUpToDateUnit: true )
323
325
}
324
326
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
+
325
337
/// Wait for all in-progress index tasks to finish.
326
338
package func waitForUpToDateIndex( ) async {
327
339
logger. info ( " Waiting for up-to-date index " )
328
340
// Wait for a build graph update first, if one is in progress. This will add all index tasks to `indexStatus`, so we
329
341
// can await the index tasks below.
330
- await generateBuildGraphTask ? . value
342
+ await waitForBuildGraphGenerationTasks ( )
331
343
332
344
await withTaskGroup ( of: Void . self) { taskGroup in
333
345
for (_, status) in inProgressIndexTasks {
@@ -356,7 +368,7 @@ package final actor SemanticIndexManager {
356
368
)
357
369
// If there's a build graph update in progress wait for that to finish so we can discover new files in the build
358
370
// system.
359
- await generateBuildGraphTask ? . value
371
+ await waitForBuildGraphGenerationTasks ( )
360
372
361
373
// Create a new index task for the files that aren't up-to-date. The newly scheduled index tasks will
362
374
// - Wait for the existing index operations to finish if they have the same number of files.
0 commit comments