Skip to content

Commit

Permalink
Cleanup interrupt even further (#3396)
Browse files Browse the repository at this point in the history
  • Loading branch information
bufdev authored Oct 10, 2024
1 parent 92ff0c9 commit f19fcb3
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 23 deletions.
7 changes: 1 addition & 6 deletions private/pkg/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -326,12 +326,7 @@ func Main(ctx context.Context, f func(context.Context, Container) error) {
// The run will be stopped on interrupt signal.
// The exit code can be determined using GetExitCode.
func Run(ctx context.Context, container Container, f func(context.Context, Container) error) error {
ctx, cancel := interrupt.NotifyContext(ctx)
go func() {
<-ctx.Done()
cancel()
}()
if err := f(ctx, container); err != nil {
if err := f(interrupt.Handle(ctx), container); err != nil {
printError(container, err)
return err
}
Expand Down
38 changes: 31 additions & 7 deletions private/pkg/interrupt/interrupt.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,38 @@ package interrupt

import (
"context"
"os"
"os/signal"
)

var interruptSignals = append([]os.Signal{os.Interrupt}, extraSignals...)

// NotifyContext returns a new [context.Context] from [signal.NotifyContext]
// with the appropriate interrupt signals.
func NotifyContext(ctx context.Context) (context.Context, context.CancelFunc) {
return signal.NotifyContext(ctx, interruptSignals...)
// Handle returns a copy of the parent [context.Context] that is marked done
// when an interrupt signal arrives or when the parent Context's Done channel
// is closed, whichever happens first.
//
// Signal handling is unregistered automatically by this function when the
// first interrupt signal arrives, which will restore the default interrupt
// signal behavior of Go programs (to exit).
//
// In effect, this function is functionally equivalent to:
//
// ctx, cancel := signal.NotifyContext(ctx, interrupt.Signals...)
// go func() {
// <-ctx.Done()
// cancel()
// }()
//
// Most programs should wrap their contexts using this function to enable interrupt
// signal handling. The first interrupt signal will result in the context's Done
// channel closing. The second interrupt signal will result in the program exiting.
//
// func main() {
// ctx := interrupt.Handle(context.Background())
// ...
// }
func Handle(ctx context.Context) context.Context {
ctx, cancel := signal.NotifyContext(ctx, Signals...)
go func() {
<-ctx.Done()
cancel()
}()
return ctx
}
9 changes: 4 additions & 5 deletions private/pkg/interrupt/interrupt_other.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@ package interrupt

import "os"

// extraSignals are signals beyond os.Interrupt that we want to be handled
// as interrupts.
// Signals are all interrupt signals.
//
// For unix-like platforms, this adds syscall.SIGTERM. No other signals
// are added for other platforms.
var extraSignals = []os.Signal{}
// As opposed to os.Interrupt, this adds syscall.SIGTERM for unix-like platforms. For
// other platforms, this is just os.Interrupt
var Signals = []os.Signal{os.Interrupt}
9 changes: 4 additions & 5 deletions private/pkg/interrupt/interrupt_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,8 @@ import (
"syscall"
)

// extraSignals are signals beyond os.Interrupt that we want to be handled
// as interrupts.
// Signals are all interrupt signals.
//
// For unix-like platforms, this adds syscall.SIGTERM. No other signals
// are added for other platforms.
var extraSignals = []os.Signal{syscall.SIGTERM}
// As opposed to os.Interrupt, this adds syscall.SIGTERM for unix-like platforms. For
// other platforms, this is just os.Interrupt
var Signals = []os.Signal{os.Interrupt, syscall.SIGTERM}

0 comments on commit f19fcb3

Please sign in to comment.