-
Notifications
You must be signed in to change notification settings - Fork 2k
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
cmd/docker: add cause to user-terminated context.Context
#5760
base: master
Are you sure you want to change the base?
Conversation
This patch adds a "cause" to the `context.Context` error when the user terminates the process through SIGINT/SIGTERM. This allows us to distinguish the cause of the `context.Context` cancellation. In future we would also be able to improve the UX of printed errors based on the underlying cause. Signed-off-by: Alano Terblanche <[email protected]>
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #5760 +/- ##
==========================================
- Coverage 59.47% 59.43% -0.04%
==========================================
Files 346 347 +1
Lines 29367 29422 +55
==========================================
+ Hits 17465 17488 +23
- Misses 10929 10962 +33
+ Partials 973 972 -1 |
if err != nil && !errdefs.IsCancelled(err) { | ||
ctx := context.Background() | ||
err := dockerMain(ctx) | ||
if err != nil && !errdefs.IsCancelled(err) && !errors.Is(err, errCtxUserTerminated) { |
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.
errors.Is(err, errCtxUserTerminated)
will never be true. CancelCauseFunc sets the cause of the context error and not the error itself.
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.
ctx
errors are propagated up from the stack as normal errors. L35 will contain the context error making the check for errors.Is(err, errCtxUserTerminated)
true.
But you are correct that in this PR it won't ever be true since we are incorrectly wrapping errors downstream. A fix for that is in this PR #5666.
if err != nil && !errdefs.IsCancelled(err) { | ||
ctx := context.Background() | ||
err := dockerMain(ctx) | ||
if err != nil && !errdefs.IsCancelled(err) && !errors.Is(err, errCtxUserTerminated) { |
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.
Hmm, I'm wondering. In which case would err
be IsCancelled
and not caused by L54?
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 we cancel a prompt it returns an IsCancelled
error.
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 isn't the prompt cancellation always a direct consequence of SIGINT?
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.
yes, but it was wired up to replace the error from context.Cancelled
to errdefs.Cancelled
https://github.com/docker/cli/blob/master/cli/command/utils.go#L114-L117
https://github.com/docker/cli/blob/master/cli/command/utils.go#L78
signal.Stop(ch) | ||
return | ||
case <-ch: | ||
cancel(errCtxUserTerminated) |
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 thing that I can't wrap my mind around is:
After this cancel, we'll have:
ctx.Err() = context.Canceled
context.Cause(ctx) = errCtxUserTerminated
With that in mind, how dockerMain
ends up returning the cause, instead of the ctx.Err()
? 🤔
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.
Yes you are right, essentially right now not all commands would return a cause, but the standard library should - like http.NewRequestWithContext.
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.
Go std http.Transport
returns a context.Cause
when context.Done()
https://github.com/golang/go/blob/608acff8479640b00c85371d91280b64f5ec9594/src/net/http/transport.go#L669
Signed-off-by: Alano Terblanche <[email protected]>
Signed-off-by: Alano Terblanche <[email protected]>
8839f12
to
bdd630c
Compare
This patch adds a "cause" to the
context.Context
error when the user terminates the process through SIGINT/SIGTERM.This allows us to distinguish the cause of the
context.Context
cancellation. In future we would also be able to improve the UX of printed errorsbased on the underlying cause.
- What I did
- How I did it
- How to verify it
- Description for the changelog
- A picture of a cute animal (not mandatory but encouraged)