-
Notifications
You must be signed in to change notification settings - Fork 789
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
Improve solution load performance #2133
Conversation
…to some long running project tasks
Hi @saul, I'm your friendly neighborhood Microsoft Pull Request Bot (You can call me MSBOT). Thanks for your contribution! TTYL, MSBOT; |
@saul What's a great PR. Thanks for doing this. |
Yes, this it great for large solutions. A lot of tests fail though :( |
Thanks @vasily-kirichenko - where can I find these test failures? |
Thanks again. These look relevant - I'll get on to sorting them. |
…d re-raise them as an aggregate exception
… mocks to fix tests
@saul BTW, they won't merge the PR until you sign the CLA. |
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.
@saul
Hi, we have verification to ensure that no unintended types are made public. We have quite a high compatability bar, and internal types don't count :-)
So you added a few extra public types, just make them internal and all will be well.
to repro the failure use:
build vs vstest
open System.Runtime.InteropServices | ||
open Microsoft.VisualStudio.Shell.Interop | ||
|
||
type WaitDialogOptions = |
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.
type internal WaitDialogOptions =
ShowMarqueeProgress : bool | ||
} | ||
|
||
module WaitDialog = |
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.
module internal WaitDialog =
@@ -1595,6 +1626,11 @@ namespace rec Microsoft.VisualStudio.FSharp.ProjectSystem | |||
member x.SetSpecificEditorProperty(_mkDocument:string, _propid:int, _value:obj ) = | |||
VSConstants.E_NOTIMPL | |||
end | |||
|
|||
type ActiveCfgBatchUpdateState = |
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.
type internal ActiveCfgBatchUpdateState =
@dotnet-bot test this please |
@vasily-kirichenko it's signed, see #2135. I'm not sure why it's not updated the label on this PR. @KevinRansom I've made those types internal as requested - all of the tests should pass now. |
@martinwoodward IIRC you are the one to ask when we have trouble with the CLA bots. Could you please take a look? Thanks |
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.
Do we need to address threading issues here?
| None -> () | ||
projNode.ComputeSourcesAndFlags() | ||
|
||
if batchState = BatchWaiting then |
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.
This does not look threadsafe.
Is there some mechanism in place that ensures this can never race, or should we use
Interlocked Compex or a lock?
|
||
interface IVsUpdateSolutionEvents4 with | ||
member x.OnActiveProjectCfgChangeBatchBegin() = | ||
batchState <- BatchWaiting |
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.
Ditto
member x.OnActiveProjectCfgChangeBatchBegin() = | ||
batchState <- BatchWaiting | ||
member x.OnActiveProjectCfgChangeBatchEnd() = | ||
batchState <- NonBatch |
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.
Ditto
// this will be called for each project, but wait dialogs cannot 'stack' | ||
// i.e. if a wait dialog is already open, subsequent calls to StartWaitDialog | ||
// will not override the current open dialog | ||
waitDialog <- |
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.
Is there a guarantee that OnBeforeActiveSolutionCfgChange can be called multiiple times simultaneously?
member x.OnAfterActiveSolutionCfgChange(_oldCfg, _newCfg) = | ||
match queuedWork with | ||
| Some(l) -> l |> List.iter (fun projNode -> projNode.ComputeSourcesAndFlags()) | ||
match waitDialog 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.
Races?
The code was previously thread unsafe as it appended to a list on each OnActiveProjectCfgChange (queuedWork). I don't believe there's any threading guarantees from VS, but from what I've experienced it's always called on the UI thread. I'm happy to put locks on this but I don't think they're necessary. |
Given the more pervasive use of async It seems as if there may be a justification to improving the thread safety of the code that runs in VS. That it wasn't threadsafe before is probably a poor guide to whether it should be. |
I completely understand your concerns, but although it's not explicitly mentioned in the docs, I don't believe these events can ever be called from non-UI threads. Looking at other implementations of IVsUpdateSolutionEvents in Roslyn, they also exhibit no thread safety. Would you be happy with calls to |
@saul point me the roslyn code, I will discus it with Srivatsn, see what the deal should be with that. @srivatsn, what is the threadsafety requirements for: IVsUpdateSolutionEvents4 implementations? Thanks Kevin |
Thanks Kevin. Here's a couple of references I found in Roslyn:
|
Switching between Debug and Release configurations on VisualFSharp solution: RC2 - 40 seconds (yes), this PR - 5 seconds. Absolutely awesome! The huge pause before the building even starts after pressing |
@saul .... chatting with a few folk around the team including @srivatsn and @Pilchie we are confident that VS ensures that these events are handled on the UI thread. With the caveat "Until we go to CPS and then we will have to figure this stuff out again". So .... thanks for taking care of this Kevin |
This PR fixes a few issues that I uncovered investigating #2107:
The net effect of this PR is that the following actions should have a better user experience (faster and or show wait dialogs):
There's still more to do with #2107, in particular making ComputeSourcesAndFlags faster itself. However I'll save these for a later PR.
With regards to #4, here are what the wait dialogs look like: