-
Notifications
You must be signed in to change notification settings - Fork 314
Split up-to-date status tracking and index progress tracking #1322
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Split up-to-date status tracking and index progress tracking #1322
Conversation
We were mixing the up-to-date status and in-progress status of an index task in `SemanticIndexManager`. This meant that a single `QueuedTask` in the task scheduler could be needed for eg. both preparation for editor functionality in a file of that target and to re-index a file in that target. This dual ownership made it unclear, which caller would be entitled to cancel the task. Furthermore, we needed to duplicate some logic from the preparation task dependencies in `SemanticIndexManager.prepare`. To simplify things: - Split the up-to-date status and the in-progress status into two different data structures - Make the caller of `prepare` and `scheduleIndex` responsible for cancellation of the task it has scheduled. `TaskScheduler` might receive more scheduled tasks this way but the additional tasks should all be no-ops because the status is known to be up-to-date when they execute.
@swift-ci Please test |
@swift-ci Please test Linux |
@swift-ci please test Linux platform |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
} else { | ||
// We couldn't determine which targets depend on the modified targets. Be conservative and assume all of them do. | ||
preparationStatus = [:] | ||
await indexStoreUpToDateStatus.markOutOfDate(changedFiles) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this already done a few lines above?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed
inProgressIndexTasks[file.sourceFile] = .waitingForPreparation( | ||
preparationTaskID: preparationTaskID, | ||
indexTask: indexTask | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we potentially run into a case?
- We kick off indexing for a single file
- We then schedule the indexing for a whole bunch of files that include that file
inProgressIndexTasks
gets set to the new preparation task id for the large group of files- The indexing job for the single file gets completed, but that won't be reflected in
inProgressIndexTasks
, soinProgressIndexFiles
will still list it as running - We then have to wait for the large file job to complete before the file is marked as completed
And does it matter?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we can run into that case but I don’t think it matters because the two uses of inProgressIndexFiles
are:
- Index progress reporting: The effect of this will be that the numerator of the progress will only be incremented to reflect that the single file is up-to-date only when the batch is indexed, ie. it’s lower by 1 for a little while longer. Since we’re also waiting for other files to be indexed, I don’t think it actually matters
- Waiting for an up-to-date index: In that case we want to wait for all index tasks to finish anyway, including the batch.
import SKCore | ||
|
||
/// Keeps track of whether an item (a target or file to index) is up-to-date. | ||
actor IndexUpToDateStatusManager<Item: Hashable> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could drop the Index
? Could be OperationStatusManager
? Not a huge fan of Manager
though 🤔. OperationStatusTracker
? 🤷
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I’d like to stick with UpToDate
in the name because the two states are upToDate
and outOfDate
. I’ll go with UpToDateTracker
.
await indexStoreUpToDateStatus.markOutOfDate(changedFiles) | ||
|
||
await preparationUpToDateStatus.markAllOutOfDate() | ||
// `markAllOutOfDate` only marks targets out-of-date that have been indexed before. Also mark all targets with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
markAllKnownOutOfDate
?
We were mixing the up-to-date status and in-progress status of an index task in
SemanticIndexManager
. This meant that a singleQueuedTask
in the task scheduler could be needed for eg. both preparation for editor functionality in a file of that target and to re-index a file in that target. This dual ownership made it unclear, which caller would be entitled to cancel the task. Furthermore, we needed to duplicate some logic from the preparation task dependencies inSemanticIndexManager.prepare
.To simplify things:
prepare
andscheduleIndex
responsible for cancellation of the task it has scheduled.TaskScheduler
might receive more scheduled tasks this way but the additional tasks should all be no-ops because the status is known to be up-to-date when they execute.