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
Cancellation for Executable #9522
Cancellation for Executable #9522
Conversation
See #9522 (comment) |
4a2a944
to
cc16151
Compare
Minor review comments, rebased to add cancellation after #9524 was merged #9524 (review) |
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.
👍
When forms starting list of custom diff/merge tools are closed, cancel the handling including the Git process. CustomMergeTools: Decrease delay before listing
cc16151
to
be57392
Compare
GitCommands/Git/Executable.cs
Outdated
public Task WaitForExitAsync(CancellationToken token) => _process.WaitForExitAsync(token); | ||
|
||
/// <inheritdoc /> | ||
public int WaitForExitTask() |
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 name is confusing and wrong. It returns an int
and not a task
. The same goes for the async version.
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 method "waits for the exitTask" created when the process exits, including the extra work to add to log etc.
It is not a normal WaitForExit()
that waits for the process task to exit.
I still think the name is better.
But what about WaitForProcessExit()
?
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 is the non-async form of WaitForExitAsync
so should be called WaitForExit
in order to be consistent with the rest of the framework (e.g. Read
/ReadAsync
, Write
/WriteAsycn
, ...).
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.
But there are two variants of WaitForExit() now: One that waits for the process to exit (that I added, cancellable) and the existing that waits for the additional exitTask to exit. I find the new method to follow the intention of the WaitForExit() method better, but I can rename that instead.
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.
👍
Once on .NET 6.0 we will have this: https://devblogs.microsoft.com/dotnet/new-dotnet-6-apis-driven-by-the-developer-community/#waitasync-improvements
Was that for calling the existing exitTask as
Unfortunately no change here, the additional exitTask is the problem here it seems. |
It's almost a midnight here, and you're asking complex questions :D |
/// </summary> | ||
/// <param name="token">An optional token to cancel the asynchronous operation.</param> | ||
/// <returns>A task that will complete when the process has exited, cancellation has been requested, or an error occurs.</returns> | ||
Task WaitForExitAsync(CancellationToken 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.
So now we have:
/// Blocks the calling thread until the process exits, or when this object is disposed.
int WaitForProcessExit();
/// Returns a task that completes when the process exits, or when this object is disposed.
Task<int> WaitForProcessExitAsync();
/// Instructs the process component to wait for the associated process to exit, or for the cancellationToken to be cancelled (cancells the process).
Task WaitForExitAsync(CancellationToken token);
Maybe we can do something like this, and remove the need for the new method?
public Task<int> WaitForProcessExitAsync(CancellationToken token)
{
token.Register(() => _exitTaskCompletionSource.SetCanceled(token));
return _exitTaskCompletionSource.Task;
}
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.
Not really an option, exitTask is awaiten together with tasks for stdout and possibly stderr.
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.
May be an option, I do not get the cancellation working though.
Will be away from the compiler for a few days
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 did not get this working, just renaming
When forms starting list of custom diff/merge tools are closed, cancel the handling including the Git process. CustomMergeTools: Decrease delay before listing
2d3ea9d
to
7dc2df2
Compare
Rebased, renamed |
7dc2df2
to
7e998e3
Compare
When forms starting list of custom diff/merge tools are closed, cancel the handling including the Git process. CustomMergeTools: Decrease delay before listing
7e998e3
to
6dd3a7d
Compare
We can iterate on this later, if necessary. |
I am considering setting the priority for the long running and Git "background" processes to BelowNormal Probably very little difference for users though |
How do we tell whether a process is expected to be a long running one?
|
By knowledge, those we know may be long (currently these two in the PR). But this fit in other PRs. I may look at this after the blame/filter PRs are merged |
Cleanup: Remove unnecessary explicit throw if cancelled
When forms starting list of custom diff/merge tools are closed, cancel the handling including the Git process. CustomMergeTools: Decrease delay before listing
6dd3a7d
to
e71339c
Compare
Fixes #9440
#9440 is mostly closed in #9505, this handles a few effects
Closes #9501
Proposed changes
Long running process like "git difftool --tool-help" are currently never cancelled, they must run to exit.
I have seen this command require over a minute at work.
After #9505, there is no major problem due to this, it is possible to open the console and close GE quickly after opening, but it could be a potential issue.
CancellationToken for Executable
Possibility to cancel processes, not hanging until closing.
There may be other ways to do this too.
CancellationToken handling for CustomDiffMergeTools
Runs in the background and was never cancelled before. This add cancellation token handling and also cancels the Git command.
A few other cleanups, review commit by commit
Test methodology
Manual
Solve merge conflicts...
formmergetool --tool-help
in the listMerge strategy
I agree that the maintainer squash merge this PR (if the commit message is clear).
✒️ I contribute this code under The Developer Certificate of Origin.