dotnet / fsharp

The F# compiler, F# core library, F# language service, and F# tooling integration for Visual Studio
https://dotnet.microsoft.com/languages/fsharp
MIT License
3.92k stars 785 forks source link

VS sometimes runs more than one incremental builder for the same project #15060

Open majocha opened 1 year ago

majocha commented 1 year ago

image

This causes wasted CPU work and multiplied allocations. It does not seem intentional.

0101 commented 1 year ago

It's expected to have multiple builders per project under some circumstances. Notably when any references are updated.

https://github.com/dotnet/fsharp/blob/f1653583c2823e784308fab19a9fb934d18a385a/src/Compiler/Service/IncrementalBuild.fs#L1148-L1149

There's also a lot going on with FSharpProjectOptions processing on VS startup, which could possibly also generate multiple options for one project which are not AreSameForChecking and thus would produce multiple builders.

majocha commented 1 year ago

I wonder what's going on here:

https://github.com/dotnet/fsharp/blob/ea5a144e71cc63b86f9e96dcb9f395691cdd062a/src/Compiler/Service/service.fs#L426-L445

when builderOpt.IsNone -> return builderOpt does not feel right or intended.

majocha commented 1 year ago

It's expected to have multiple builders per project under some circumstances. Notably when any references are updated.

https://github.com/dotnet/fsharp/blob/f1653583c2823e784308fab19a9fb934d18a385a/src/Compiler/Service/IncrementalBuild.fs#L1148-L1149

There's also a lot going on with FSharpProjectOptions processing on VS startup, which could possibly also generate multiple options for one project which are not AreSameForChecking and thus would produce multiple builders.

The problem I've seen is not only them being created but both running to completion, parsing and typechecking everything twice. This however seem to happen in VS only for the first file opened, and not the subsequent ones.

So it's more of a glitch than a showstopper after all 😀

majocha commented 1 year ago

I've also seen VS not cancelling the type check when it should. For example closing the solution will not stop the type check. If the project options update a few times during solution load, and in the meantime some analyzers are being run on the opened documents, and they don't cancel on project options change, we would see multiple typechecks running in parallel on the same files. That's what I sometimes observe.

auduchinok commented 1 year ago

I think I could've seen it in Rider too some time ago. It's OK if there are multiple builders for the same project given that the options are different (e.g. different target frameworks, or before/after a project modifications), but it seems that there should be no builders that have the same options, I'd expect them to be shared in such a case.

psfinaki commented 2 months ago

So regarding this one - I have spent some time on it today, compiling the compiler and looking into what's happening in the language service.

I didn't really notice something sensational there, especially in the light of comments above. Multiple builders are spun up sometimes, but there could be legitimate reasons for that and it doesn't seem like it's getting "out of control".

Given extra information in the comments (if this happens then probably only on the startup) and low activity here for the last year, I'd deprioritize this a bit and wait for a solid repro - i.e. some particular code which spins up something that it shouldn't.

@vzarytovskii

psfinaki commented 2 months ago

(discussed offline, agreed on the above)