Skip to content

When interacting with a document, prepare the target it belongs to #1307

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

Merged
merged 2 commits into from
May 16, 2024

Conversation

ahoppen
Copy link
Member

@ahoppen ahoppen commented May 16, 2024

Whenever we get request for a document, open it or edit it, trigger a preparation of its target, but don’t block any interaction based on it. This should ensure that the target is usually prepared when the user is interacting with it.

We need to track the preparation status of targets somewhat accurately in SemanticIndexManager, so we don’t unnecessarily re-prepare a target. When updating the index store, it is acceptable to schedule another UpdateIndexStoreTaskDescription because it will early exit based on an mtime check with the unit file. Null builds of a target take significantly longer and thus we want to avoid them.

Fixes #1252
Fixes #1258
rdar://127474003
rdar://127475948
rdar://127473987

@ahoppen ahoppen requested review from bnbarham and hamishknight May 16, 2024 05:21
@ahoppen ahoppen requested a review from benlangmuir as a code owner May 16, 2024 05:21
@ahoppen
Copy link
Member Author

ahoppen commented May 16, 2024

@swift-ci Please test

Comment on lines +279 to +284
if configuredTargets.count <= targets.count {
preparationTasksToAwait.append(task)
}
fallthrough
case nil:
targetsToPrepare.append(target)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might be misunderstanding, but won't this mean that we'd still schedule the preparation again for the same target if we already have one running?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it does and that’s intentional, in the context of multi-target preparation. Say that while background indexing you are preparing targets A, B, and C in a single SwiftPM invocation (like a hypothetical swift prepare --target A --target B --target C), which has the benefit that it allows concurrent building of the three targets if they don’t depend on each other.

Now you are trying to work on a file in A, which requires target A to be prepared. Now, you don’t want to wait for preparation of all three targets to finish, but want to build target A as quickly as possible. So, you schedule preparation of A with high priority, which will cancel and reschedule the preparation of A, B and C in TaskScheduler. Once preparation of A has finished, the joint preparation of A, B, and C is re-scheduled, which will effectively only need to prepare B and C because the build system realizes that A is already up-to-date.

Does that make sense?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that makes sense. I was mainly thinking of the case where you have A being prepared and get a new request to prepare A, we'll schedule it again. Though I wasn't really thinking about the scheduling logic, now that I think about it, we'll make the subsequent request wait on the former, and then when evaluating it should be a no-op, so I guess this isn't the end of the world.

Copy link
Contributor

@hamishknight hamishknight May 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment doesn't quite seem true though:

        // target's preparation status with a longer-running task. The key benefit here is that when we get many
        // preparation requests for the same target (eg. one for every text document request sent to a file), we don't
        // re-create new `PreparationTaskDescription`s for every preparation request. 

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I was just missing a break here.

ahoppen added 2 commits May 16, 2024 10:08
…hat are known to be up-to-date

Fixes swiftlang#1258
rdar://127475948
Whenever we get request for a document, open it or edit it, trigger a preparation of its target, but don’t block any interaction based on it. This should ensure that the target is usually prepared when the user is interacting with it.

We need to track the preparation status of targets somewhat accurately in `SemanticIndexManager`, so we don’t unnecessarily re-prepare a target. When updating the index store, it is acceptable to schedule another `UpdateIndexStoreTaskDescription` because it will early exit based on an `mtime` check with the unit file. Null builds of a target take significantly longer and thus we want to avoid them.

Fixes swiftlang#1252
rdar://127474003
@ahoppen ahoppen force-pushed the background-prepare-targets branch from 6f65659 to 7208376 Compare May 16, 2024 17:40
@ahoppen ahoppen changed the title When interacting with a document, prepare the target it belongs to 🚥 #1306 When interacting with a document, prepare the target it belongs to May 16, 2024
@ahoppen
Copy link
Member Author

ahoppen commented May 16, 2024

@swift-ci Please test

@ahoppen
Copy link
Member Author

ahoppen commented May 16, 2024

@swift-ci Please test Windows

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Track which targets are up-to-date Prepare target when a file is opened
2 participants