Skip to content

Keep track of build settings in BuildSystemManager instead of SourceKitServer #841

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

Conversation

ahoppen
Copy link
Member

@ahoppen ahoppen commented Sep 30, 2023

After two minor preliminary commits, there are two core commits here that go hand-in-hand and significantly simplify the build settings handling.

Change the build system to only notify delegate about changed files, not about new build settings

This defines away an entire class of data races if delegate callbacks are delivered out-of-order. If we aren’t providing the new build settings in the delegate callback, then it doesn’t matter if two fileBuildSettingsChanged calls change order since they don’t carry any state. Instead of storing the build settings returned by the delegate call, the language server needs to ask the BuildSystemManager for the current build settings of the file.

Remove tracking of file build settings status in SourceKitServer and BuildSystemManager

The core idea here is that the toolchain language servers always call into BuildSystemManager and BuildSystemManager will always reply with build settings. If it hasn’t computed them yet, it will reply with fallback settings.

With that assumption, we can remove the documentToPendingQueue from SourceKitServer since there are no longer any documents that are pending – everything has a build settings immediately.

Similarly, BuildSystemManager.mainFileStatuses also isn’t needed anymore.

And lastly, since we know that BuildSystemManager.buildSettings will always return a value registerForChangeNotifications is changed not call fileBuildSettingsChanged immediately. Instead, it will only cause fileBuildSettingsChanged to be called when the file’s build settings change after the registerForChangeNotifications call.

@ahoppen ahoppen force-pushed the ahoppen/build-settings-pull branch from ea6158f to 9a2c57f Compare September 30, 2023 05:07
@ahoppen
Copy link
Member Author

ahoppen commented Sep 30, 2023

@swift-ci Please test

@ahoppen
Copy link
Member Author

ahoppen commented Sep 30, 2023

@swift-ci Please test macOS

…not about new build settings

This defines away an entire class of data races if delegate callbacks are delivered out-of-order. If we aren’t providing the new build settings in the delegate callback, then it doesn’t matter if two `fileBuildSettingsChanged` calls change order since they don’t carry any state.
…d `BuildSystemManager`

The core idea here is that the toolchain language servers always call into `BuildSystemManager` and `BuildSystemManager` will always reply with build settings. If it hasn’t computed them yet, it will reply with fallback settings.

With that assumption, we can remove the `documentToPendingQueue` from `SourceKitServer` since there are no longer any documents that are pending – everything has a build settings immediately.

Similarly, `BuildSystemManager.mainFileStatuses` also isn’t needed anymore.

And lastly, since we know that `BuildSystemManager.buildSettings` will always return a value `registerForChangeNotifications` is changed not call `fileBuildSettingsChanged` immediately. Instead, it will only cause `fileBuildSettingsChanged` to be called when the file’s build settings change after the `registerForChangeNotifications` call.
@ahoppen ahoppen changed the base branch from main to ahoppen/asyncification October 2, 2023 17:16
@ahoppen ahoppen force-pushed the ahoppen/build-settings-pull branch from 9a2c57f to c642b37 Compare October 2, 2023 17:16
Copy link
Contributor

@hamishknight hamishknight left a comment

Choose a reason for hiding this comment

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

Nice!

for document: DocumentURI,
language: Language
) async -> (buildSettings: FileBuildSettings, isFallback: Bool)? {
if let mainFile = mainFilesProvider?.mainFilesContainingFile(document).first {
Copy link
Contributor

Choose a reason for hiding this comment

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

As I understand it, mainFilesContainingFile returns a Set, do we need to worry about the lack of a stable ordering when accessing first?

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah I see this is copying chooseMainFile, do we need to worry there too?

Copy link
Member Author

Choose a reason for hiding this comment

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

It turned out that this was a good area to refactor and it got a little bit larger and more involved. I will open a follow-up PR for it.

Comment on lines -273 to -284
// If the document is ready, we can handle it right now.
guard !self.documentsReady.contains(doc) else {
await requestHandler(request, workspace, languageService)
return
}

// Not ready to handle it, we'll queue it and handle it later.
self.documentToPendingQueue[doc, default: DocumentNotificationRequestQueue()].add(operation: {
await requestHandler(request, workspace, languageService)
}, cancellationHandler: {
request.reply(fallback)
})
Copy link
Contributor

Choose a reason for hiding this comment

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

🎉

@ahoppen ahoppen merged commit e1548a0 into swiftlang:ahoppen/asyncification Oct 2, 2023
@ahoppen ahoppen deleted the ahoppen/build-settings-pull branch October 2, 2023 23:56
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.

2 participants