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
FormBrowse init optimizations #9729
FormBrowse init optimizations #9729
Conversation
48c425d
to
d644fbe
Compare
d644fbe
to
26f9b6e
Compare
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.
Some explanations to changes
@@ -447,11 +448,9 @@ protected override void OnLoad(EventArgs e) | |||
{ | |||
_formBrowseMenus.CreateToolbarsMenus(ToolStripMain, ToolStripFilters, ToolStripScripts); | |||
|
|||
HideVariableMainMenuItems(); |
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.
Run from SetGitModule()
, always run before opening module or dashboard so no explicit call needed.
RefreshSplitViewLayout(); | ||
LayoutRevisionInfo(); | ||
SetSplitterPositions(); | ||
InternalInitialize(false); |
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.
Method has repo specific setup and runs from RefreshRevisions()
Previously needed here as it must run after RevisionGrid.ForceRefreshRevisions()
GitUI/CommandsDialogs/FormBrowse.cs
Outdated
|
||
// We're launching the main form, and whilst the module has been set for us we still need to formally switch to it | ||
SetGitModule(this, new GitModuleEventArgs(new GitModule(Module.WorkingDir))); | ||
|
||
RevisionGrid.ResumeRefreshRevisions(); | ||
RefreshRevisions(); |
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.
Previously, RevisionGrid.ResumeRefreshRevisions()
would run RevisionGrid.ForceRefreshRevisions()
only, so some other methods in RefreshRevisions()
had to run in OnLoad()
@@ -572,22 +570,33 @@ private void RefreshRevisions() | |||
return; | |||
} | |||
|
|||
_gitStatusMonitor.InvalidateGitWorkingDirectoryStatus(); |
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.
Run from SetGitModule()
{ | ||
revisionDiff.RefreshArtificial(); | ||
RevisionGrid.ForceRefreshRevisions(); | ||
RevisionGrid.IndexWatcher.Reset(); |
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.
Runs in RevisionGrid.ForceRefreshRevisions()
|
||
InternalInitialize(); | ||
|
||
RefreshGitStatusMonitor(); |
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.
Let the separate git-status calls run after the UI is refreshed
GitUI/CommandsDialogs/FormBrowse.cs
Outdated
@@ -1800,7 +1810,6 @@ private void SetGitModule(object sender, GitModuleEventArgs e) | |||
|
|||
// If we're applying custom branch or revision filters - reset them | |||
RevisionGrid.DisableFilters(); | |||
SetPathFilter(pathFilter: null); |
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 triggers a Grid refresh, so this must not occur (see also comments for the commit).
Maybe the CanRefresh
check in
Maybe add RevisionGrid.SuspendRefreshRevisions()
/RevisionGrid.ResumeRefreshRevisions()
in GitSetModule
to permanently avoid this as the refresh is done in UICommands_PostRepositoryChanged()
Edit: Changed this to use RevisionGrid.SuspendRefreshRevisions()
/RevisionGrid.ResumeRefreshRevisions()
in GitSetModule
and Debug.Assert
in RequestRefresh
.
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 is likely because of the changes to ResumeRefreshRevisions
@@ -572,22 +570,33 @@ private void RefreshRevisions() | |||
return; | |||
} | |||
|
|||
_gitStatusMonitor.InvalidateGitWorkingDirectoryStatus(); | |||
RequestRefresh(); |
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.
Renamed to RefreshGitStatusMonitor
26f9b6e
to
fbf148f
Compare
fbf148f
to
dad22be
Compare
3901b2b
to
dad22be
Compare
if (_updatingFilters == 0) | ||
{ | ||
ForceRefreshRevisions(); | ||
} |
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.
Coupled with above comment I'm finding this change the most puzzling. This was meant to guard against nested unbalanced suspensions (i.e., without a resume call), and execute a refresh only on the outer scope.
Now it feels like we may be returning into a realm where we may be calling multiple refreshes.
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.
See above, the refresh is always called explicitly after Suspend/Resume.
GitUI/CommandsDialogs/FormBrowse.cs
Outdated
} | ||
|
||
toolStripButtonPush.DisplayAheadBehindInformation(Module.GetSelectedBranch()); | ||
Debug.Assert(RevisionGrid.CanRefresh, "Already loading revisions when running RefreshRevisions(). This could cause the commits in the grid to be loaded several times."); | ||
RevisionGrid.ForceRefreshRevisions(); |
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.
💭 Generally speaking we should strive to avoid calling this API.
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.
In general the changes look sensible and positive, however I am not quite content with the changes to ResumeRefreshRevisions
- I spent a considerable time checking various code paths (primarily in the context of filters) to reduce redundant refreshes.
This PR is required to avoid that the left panel is init twice in #9734, and for #9735 that can save seconds opening a repo.
I also have spent considerable time debugging and trying to understand what the intention was. The handling was not easy before, but the changed handling does not go all the way. I tried to explain the changes in my review, another try here: The handling after GE has started once is not changed much, just some adjustments.
The startup had another path:
This PR changes the start:
This change was probably not enough,
These are now pure guards, the refresh is always done in post repo change.
All revision reading related to repo changes is now in |
dad22be
to
cee96f0
Compare
cee96f0
to
cc53627
Compare
cc53627
to
9e74d91
Compare
I ran it locally with few different filters, and I couldn't observer any reentrancy I was worried about. So 👍 from me. |
public bool CanRefresh => !_isRefreshingRevisions && _updatingFilters == 0; | ||
|
||
/// <summary> | ||
/// Queries git for the new set of revisions, and refreshed the grid. |
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.
Rename is of course fine, will just change this wording.
/// Queries git for the new set of revisions, and refreshed the grid. | |
/// Queries git for the new set of revisions and refreshes the grid. |
OK to squash and merge?
I would like to get #9735 ready to merge, that is both improving startup a lot and seem to improve test stability.
GitUI/CommandsDialogs/FormBrowse.cs
Outdated
@@ -582,7 +582,7 @@ private void RefreshRevisions() | |||
} | |||
|
|||
Debug.Assert(RevisionGrid.CanRefresh, "Already loading revisions when running RefreshRevisions(). This could cause the commits in the grid to be loaded several times."); | |||
RevisionGrid.ForceRefreshRevisions(); | |||
RevisionGrid.RefreshRevisions(); |
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 must be PerformRefreshRevisions()
(that must be public again.
9e74d91
to
29a10f5
Compare
29a10f5
to
2d8d21b
Compare
Reorganize the startup so also first startup runs all repo related operations in PostRepositoryChanged. Before some init operations had to run several times at the startup.
2d8d21b
to
2b1d42b
Compare
Proposed changes
@RussKie has refactored FormBrowse init and filter handling recently.
After this handling some logic like InternalInitialize() was running several times.
This included a few Git commands too, delaying the startup slightly.
There are some test instabilities for FormBrowse, this is an attempt to at least improve investigation.
I initially got som stability issues with this change when testing in isolation but this works better when restructuring commits.
'Loading Revisions' didn't finish in 100 iterations
can still occurTest methodology
There are tests for this already
Merge strategy
Rebase merge
✒️ I contribute this code under The Developer Certificate of Origin.