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 robustness of GitStatusMonitor #10743
Improve robustness of GitStatusMonitor #10743
Conversation
@@ -469,10 +473,7 @@ private void Update() | |||
} | |||
} | |||
|
|||
if (!cancelToken.IsCancellationRequested) |
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.
Cancellation is done in ScheduleNextInteractiveTime(), then _commandIsRunning is set to false so a new command can be started.
This could allow starting a second command, not wanted.
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.
Have a look at line 249, please.
This could allow starting a second command, not wanted.
There cannot be a command running here (it has finished or been cancelled).
What do you mean with "second command"? How could it be triggered?
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 line 180, called from FormBrowse.
The Git command runs async, a second invocation can be done in the timer loop.
It occasionally occurred in 3.3 or so when git-status was slow, then git-status running in parallel used all resources.
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.
Then rather a1d7b20 and let the cancellation do the job, i.e. let it reset _commandIsRunning
in the finally
block.
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.
It may take longer time to start the next refresh (not starting the new until the first is cancelled), but no big difference and the code is easier to understand.
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.
I have finally got how it was meant. So mainly renaming and some complements.
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.
+1
Leave it to someone else to review the comment I had and to approve. Otherwise fine, have not run.
a1d7b20
to
3d6a12a
Compare
I still have the opinion that the addition on line 440 is the correct. |
@@ -455,7 +490,7 @@ private void Update() | |||
{ | |||
lock (_statusSequence) | |||
{ | |||
if (_commandIsRunning && !ModuleHasChanged() && !cancelToken.IsCancellationRequested) | |||
if (!ModuleHasChanged() && !cancelToken.IsCancellationRequested) |
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.
What about the following?
Keep line 521; _commandIsRunning = false;
if (!ModuleHasChanged() && !cancelToken.IsCancellationRequested) | |
if (cancelToken.IsCancellationRequested) | |
{ | |
return; | |
} | |
if (!ModuleHasChanged()) |
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.
I haven't had the time yet to think about your comments in detail. But I have watched it for long time and think to know two things for sure:
- The GitStatusMonitor stops doing anything because of
_commandIsRunning is true
(only resolvable by switching repos). - If we reach this
finally
block,GitExecutable.ExecuteAsync()
has finished or been cancelled, i.e. nothing is pending in GE.
What have I missed?
The git.exe
might continue to run detached in the background. We do not need to take care, don't we?
(I started to send Ctrl+C
and to terminate the process on timeout - unfinished.)
Keep line 521; _commandIsRunning = false;
I understand your concern about the delay. I need to take time thinking about how to do it without mixing states.
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.
Suggestion in fa36ff1
(_commandIsRunning is more closely related to the cancellation token).
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.
Looks fine, basically what I have been using the last days.
Have not tried to provoke errors though.
The monitor stopped running once for me (in wsl), no real stress test either. |
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.
The naming inhibits my ability to fully grasp the change.
/// <summary> | ||
/// git-status command is running that is not cancelled | ||
/// </summary> | ||
private bool _uncancelledCommandIsRunning; |
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.
"uncancelled" this looks very odd, ditto for "is running that is not cancelled" - this sounds like an oxymoron...
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 running that is not cancelled" - this sounds like an oxymoron...
In a few more words: git-statis is started and the status is nether completed (with success or error) or cancelled explicitly. If false, a new git-status can be started.
I do not have a better description. the variably name can be composed from the words in the description too.
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.
Why the original name didn't work?
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.
@mstv suggested it was a clarification, I can live with that quirky name
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.
The only clear meaning of a _commandIsRunning
would be:
try
{
_commandIsRunning = true;
RunTheCommand()
}
finally
{
_commandIsRunning = false;
}
without any conditions.
If it deviates from this scheme, it should be reflected in the identifier - not hidden in the docs.
It should be clear, why this flag must not be reset in case of cancellation. Cancelled commands are detached and ignored. We don't want to wait for their cancellation and start the next command in parallel.
_commandIsRunningAndUncancelled
might be clearer.
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.
The renaming is not a behavior change. It is a clarification. The missing edge-case handling is completed.
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.
"Uncancelled" is triggering me :) It's so Unenglish (pun intended).
How about _commandRunningWithoutCancellation
or _commandIsRunningAndNotCancelled
?
224ef1a
to
a958a47
Compare
Time to merge? |
Fixes #9955
Proposed changes
InvalidateGitWorkingDirectoryStatus()
, too, on enter ofGitStatusMonitorState.Stopped
Test methodology
Test environment(s)
Merge strategy
Please do not squash merge this PR
✒️ I contribute this code under The Developer Certificate of Origin.