-
Notifications
You must be signed in to change notification settings - Fork 790
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
Fixed .NET SDK style project slowness in the editor #4889
Conversation
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.
Nice work.
Nice 👍 |
This code deserves a small unit test :) |
But first merge it so that it's going into 15.7.2 ;-) |
Great work. |
Could you take a while to think how to put this under automated test? It's important never to regress this... The test suite has oodles of tests to check we dont reconpute/invalidate, counting number of parses, checks etc. But that only works if you get the project options right. |
The fix needs adjusting... We should not be calling UpdateProjectInfo at all during editing.... |
I agree we should put a test here so we don't regress. At the top of my head, I'm not sure how to accomplish this as it's really in the middle of a lot of stuff. Unless we already have mocks, this will be quite a bit of work to do. At some point we are going to refactor parts of the integration with the workspace. Perhaps during that time we can design something that is testable, isolated from the language service and workspace. |
I'll try to think of something. |
As for |
Do you have a callstack for when UpdateProjectInfo is being called during standard editing? |
I don't on hand. I can get one next time I go into the office. |
Your best bet is to look at the workspace events and see how it eventually calls UpdateProjectInfo. |
Oh I see, yes. The following CPS-specific path from
I asked this question when reviewing this code, when @cartermp proposed a fix for another manifestation of this problem in #4121:
However I got no reply - @KevinRansom please make sure to keep track of questions like this and make sure they get a reply? Anyway, I strongly believe that we that we should simply not be updating the project info on DocumentChanged. The only case where we might do that is for scripts, but they are handled differently. |
Anyway, I believe the correct fix is just to delete the event handler for OnDocumentChanged. And if that isn't a correct fix (I think it is) then we really need to work out why the event handler is needed.... |
Deleting it would be ideal. We should also delete it from the |
Can it result with loss of updating project options for FSX files when |
Good question. Script files are covered by this code in
But the behaviour you mention should be checked as part of validating the fix .
@TIHan do you have a link for that? |
@vasily-kirichenko that's an interesting point. I wonder if adding For script files, we should be using the MiscellaneousFilesWorkspace which we are currently not. If we used that workspace, we could at least separate its specific behavior from the workspace for projects. |
@dsyme https://github.com/TIHan/visualfsharp/blob/a6fc8525b8fec6affdef69361d3847829b9d4314/vsintegration/src/FSharp.Editor/LanguageService/LanguageService.fs#L658 There it is. You can see the specific CPS path. |
Yeah, there are a couple of glitches with script files (e.g. loss of colorization on save-as file rename) that can likely be fixed by updating script file options on changes like these
Perhaps SetupNewTextView is just the wrong place to be setting up the options for out-of-project files and scripts, and that doing it in response to the events above will be more complete and accurate (and more portable too - we'd like to eventually use FSharp.Editor in VS for Mac, so the less VS-specific code the better. Roslyn and Roslyn CPS-specific code is ok). |
Then this fix needs to evolve a bit more. Sorry I didn't test that case.
This is exactly what we need to do. We should always listen to the workspace to give us what we need. Right now we rely on HandleCommandLineArgs method until we figure out how to get rid of it. We need to integrate with the evaluation/design-time builds. |
OK, I understand now. I added some comments to clarify the existing code here. Could you check the comments, particularly this one? Let me explain a bit about |
Oh, they are existing glitches, not glitches in this PR. See #1944
I believe so, but should be checked. |
SetupNewTextView absolutely is the wrong place to setup for script files. I had a PR about a year ago which got rid of this override entirely. But when CPS support got added, it had extra stuff added to it. See https://github.com/Microsoft/visualfsharp/pull/2909/files Instead of hooking onto SetupNewTextView, I hooked onto IVsRunningDocumentTable. The code is basically a stripped down version of the MiscellaneousFilesWorkspace (which we couldn’t use from F# at the time, we now can). We should integrate with the MiscellaneousFilesWorkspace instead - it was designed entirely for script files. |
PR is updated. I'm going to add a generated netcore solution so we can easily test this. |
Tests have been added. |
test Windows_NT Release_ci_part2 Build please |
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.
Great job, love the tests. Now we all have really big .NET SDk solutions we can stress test on :)
So the solution was to delete code that was already flag with weird comment? |
@cartermp it's too late for 15.7.2? |
@forki It's highly likely that it's too late for 15.7.2. Approvals for bugs we wanted to take for that went out last week. |
Another valueable one to user test is SQLProvider: https://github.com/fsprojects/SQLProvider It's definitely suffering today |
@cartermp Are nightlies and master now usable with dev 15.7? We should put out some kind of announcement when that switch happens? (I'm not on dev 15.7 yet) |
Yes for both: https://dotnet.myget.org/feed/fsharp/package/vsix/VisualFSharp We're producing 15.7.x versions for master and a build of a VSIX ought to do the same. No real need for announcement, as this is the standard state of things. There was just an issue for a few days where we didn't merge back into master such that it would produce the correct VSIX versions. |
Doing some more testing today. So the |
Ok, I think I know what's happening from my last comment. It's because of multi-targetting. Mutli-targetted projects, are treated as two separate logical projects in the workspace. My hypothesis is that FCS only keys off of the project file name, rather than project file name and TFM. When this happens, there could be a race condition, and depending on the race condition will kick off invalidation and rebuild the world. So this is a bug already today and is not from our current changes made here. Perhaps I can make another PR to fix multi-targeting. |
Just a note about As @saul said, we should definitely be hooking into |
Couple of questions:
|
@@ -439,7 +438,6 @@ type internal FSharpLanguageService(package : FSharpPackage) = | |||
| WorkspaceChangeKind.ProjectAdded -> this.OnProjectAdded(args.ProjectId) | |||
| WorkspaceChangeKind.ProjectReloaded -> this.OnProjectReloaded(args.ProjectId) | |||
| WorkspaceChangeKind.DocumentAdded -> this.OnDocumentAdded(args.ProjectId, args.DocumentId) | |||
| WorkspaceChangeKind.DocumentChanged -> this.OnDocumentChanged(args.ProjectId, args.DocumentId) |
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.
Strange that DocumentChanged
was in this list twice already. Also - consider whether DocumentInfoChanged
should result in a call.
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.
We should probably look into that. If we find that we need to add it in, we'll make a separate PR for that one.
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.
Thinking about this, once we move away from handlecommandlinargs, we will need to listen to DocumentInfoChanged most likely.
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.
We didn't see any DocumentInfoChanged events - when do they arise?
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.
For example when the filename changes, etc:
/// <summary>
/// The document in the current solution had is info changed; name, folders, filepath
/// </summary>
DocumentInfoChanged = 17,
We should probably not check in generated projects now that I'm thinking about it. I think the C# solutions are there for us to test against the F# ones to see if we match perf. All of this is a manual process. You just run fsi on the script. |
The advantage of checking it in is that contributors usually have it easier
to use it. Also we have history of it (which can also be seen as a downside
;-))
Will Smith <notifications@github.com> schrieb am Mo., 14. Mai 2018, 18:24:
… We should probably not check in generated projects now that I'm thinking
about it.
I think the C# solutions are there for us to test against the F# ones to
see if we match perf.
All of this is a manual process. You just run fsi on the script.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#4889 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AADgNHEUd-0K-9fJl5RrT__FQ6eokPU2ks5tya_LgaJpZM4T8PFR>
.
|
I'm removing the generated projects. I think it is fine to run the generation manually by invoking fsi. This keeps the commits much clearer than seeing 100s of generated files being committed. If we really want the generated projects to be committed, we can make a separate PR. |
Yes make a separate PR please. The huge advantage of having them in the tree is that everyone, everywhere has exactly the same baselines to test against for VS perf, without any effort. That's incredibly valuable. We already have legacy projects checked in, so please, I really want .NET SDK ones too. |
As said above +1 for checking them in. We already saw benefits of checked in test projects in older issues. |
I’m for checking them in too. Another reason: the generation script does not work on Mac out of the box due to the windows style slashes in paths. |
Okay - I'll withdraw any objections about having the test files checked in. |
This was something; took quite a bit of time tracking down, but now it's starting to make sense.
Edited
We changed the approach on how we fix this problem. Essentially, we are removing calls to
UpdateProjectInfo
on document opened/changed.Test Plan
tests/projects/stress
and check load time and first semantic highlightingInclude=None
.Include=None
Include=Compile
.fs
file without a project loaded.fs
file where a project loaded .net sdk / legacy.fsx
script file where a project loaded .net sdk / legacySortedMap.fs
in Spreads, time to semantic highlighting after re-open..fs
file, time to semantic highlighting after re-open.