Merge pull request #5970 from cpuguy83/cancel_on_signal

This commit is contained in:
Fu Wei 2021-09-16 09:26:22 +08:00 committed by GitHub
commit 7d6e9773ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 63 additions and 24 deletions

View File

@ -111,13 +111,15 @@ can be used and modified as necessary as a custom configuration.`
} }
app.Action = func(context *cli.Context) error { app.Action = func(context *cli.Context) error {
var ( var (
start = time.Now() start = time.Now()
signals = make(chan os.Signal, 2048) signals = make(chan os.Signal, 2048)
serverC = make(chan *server.Server, 1) serverC = make(chan *server.Server, 1)
ctx = gocontext.Background() ctx, cancel = gocontext.WithCancel(gocontext.Background())
config = defaultConfig() config = defaultConfig()
) )
defer cancel()
// Only try to load the config if it either exists, or the user explicitly // Only try to load the config if it either exists, or the user explicitly
// told us to load this path. // told us to load this path.
configPath := context.GlobalString("config") configPath := context.GlobalString("config")
@ -161,7 +163,7 @@ can be used and modified as necessary as a custom configuration.`
return nil return nil
} }
done := handleSignals(ctx, signals, serverC) done := handleSignals(ctx, signals, serverC, cancel)
// start the signal handler as soon as we can to make sure that // start the signal handler as soon as we can to make sure that
// we don't miss any signals during boot // we don't miss any signals during boot
signal.Notify(signals, handledSignals...) signal.Notify(signals, handledSignals...)
@ -193,18 +195,56 @@ can be used and modified as necessary as a custom configuration.`
"revision": version.Revision, "revision": version.Revision,
}).Info("starting containerd") }).Info("starting containerd")
server, err := server.New(ctx, config) type srvResp struct {
if err != nil { s *server.Server
return err err error
}
// run server initialization in a goroutine so we don't end up blocking important things like SIGTERM handling
// while the server is initializing.
// As an example opening the bolt database will block forever if another containerd is already running and containerd
// will have to be be `kill -9`'ed to recover.
chsrv := make(chan srvResp)
go func() {
defer close(chsrv)
server, err := server.New(ctx, config)
if err != nil {
select {
case chsrv <- srvResp{err: err}:
case <-ctx.Done():
}
return
}
// Launch as a Windows Service if necessary
if err := launchService(server, done); err != nil {
logrus.Fatal(err)
}
select {
case <-ctx.Done():
server.Stop()
case chsrv <- srvResp{s: server}:
}
}()
var server *server.Server
select {
case <-ctx.Done():
return ctx.Err()
case r := <-chsrv:
if r.err != nil {
return err
}
server = r.s
} }
// Launch as a Windows Service if necessary // We don't send the server down serverC directly in the goroutine above because we need it lower down.
if err := launchService(server, done); err != nil { select {
logrus.Fatal(err) case <-ctx.Done():
return ctx.Err()
case serverC <- server:
} }
serverC <- server
if config.Debug.Address != "" { if config.Debug.Address != "" {
var l net.Listener var l net.Listener
if isLocalAddress(config.Debug.Address) { if isLocalAddress(config.Debug.Address) {

View File

@ -36,7 +36,7 @@ var handledSignals = []os.Signal{
unix.SIGPIPE, unix.SIGPIPE,
} }
func handleSignals(ctx context.Context, signals chan os.Signal, serverC chan *server.Server) chan struct{} { func handleSignals(ctx context.Context, signals chan os.Signal, serverC chan *server.Server, cancel func()) chan struct{} {
done := make(chan struct{}, 1) done := make(chan struct{}, 1)
go func() { go func() {
var server *server.Server var server *server.Server
@ -61,11 +61,10 @@ func handleSignals(ctx context.Context, signals chan os.Signal, serverC chan *se
log.G(ctx).WithError(err).Error("notify stopping failed") log.G(ctx).WithError(err).Error("notify stopping failed")
} }
if server == nil { cancel()
close(done) if server != nil {
return server.Stop()
} }
server.Stop()
close(done) close(done)
return return
} }

View File

@ -39,7 +39,7 @@ var (
} }
) )
func handleSignals(ctx context.Context, signals chan os.Signal, serverC chan *server.Server) chan struct{} { func handleSignals(ctx context.Context, signals chan os.Signal, serverC chan *server.Server, cancel func()) chan struct{} {
done := make(chan struct{}) done := make(chan struct{})
go func() { go func() {
var server *server.Server var server *server.Server
@ -54,12 +54,12 @@ func handleSignals(ctx context.Context, signals chan os.Signal, serverC chan *se
log.G(ctx).WithError(err).Error("notify stopping failed") log.G(ctx).WithError(err).Error("notify stopping failed")
} }
if server == nil { cancel()
close(done) if server != nil {
return server.Stop()
} }
server.Stop()
close(done) close(done)
return
} }
} }
}() }()