Skip to content

Commit

Permalink
cmd/docker: add cause to user-terminated context.Context
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
Benehiko committed Jan 20, 2025
1 parent f97ec69 commit 77760e2
Showing 1 changed file with 30 additions and 3 deletions.
33 changes: 30 additions & 3 deletions cmd/docker/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,43 @@ import (
"go.opentelemetry.io/otel"
)

var errCtxUserTerminated = errors.New("user terminated the process")

func main() {
err := dockerMain(context.Background())
if err != nil && !errdefs.IsCancelled(err) {
ctx := context.Background()
err := dockerMain(ctx)
if err != nil && !errdefs.IsCancelled(err) && !errors.Is(err, errCtxUserTerminated) {
_, _ = fmt.Fprintln(os.Stderr, err)
os.Exit(getExitCode(err))
}
}

func notifyContext(ctx context.Context, signals ...os.Signal) (context.Context, context.CancelFunc) {
ch := make(chan os.Signal, 1)
signal.Notify(ch, signals...)

ctx, cancel := context.WithCancelCause(ctx)

go func() {
select {
case <-ctx.Done():
signal.Stop(ch)
return
case <-ch:
cancel(errCtxUserTerminated)
signal.Stop(ch)
return
}
}()

return ctx, func() {
signal.Stop(ch)
cancel(nil)
}
}

func dockerMain(ctx context.Context) error {
ctx, cancelNotify := signal.NotifyContext(ctx, platformsignals.TerminationSignals...)
ctx, cancelNotify := notifyContext(ctx, platformsignals.TerminationSignals...)
defer cancelNotify()

dockerCli, err := command.NewDockerCli(command.WithBaseContext(ctx))
Expand Down

0 comments on commit 77760e2

Please sign in to comment.