Merge pull request #5970 from cpuguy83/cancel_on_signal
This commit is contained in:
commit
7d6e9773ac
@ -114,10 +114,12 @@ can be used and modified as necessary as a custom configuration.`
|
|||||||
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,17 +195,55 @@ can be used and modified as necessary as a custom configuration.`
|
|||||||
"revision": version.Revision,
|
"revision": version.Revision,
|
||||||
}).Info("starting containerd")
|
}).Info("starting containerd")
|
||||||
|
|
||||||
|
type srvResp struct {
|
||||||
|
s *server.Server
|
||||||
|
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)
|
server, err := server.New(ctx, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
select {
|
||||||
|
case chsrv <- srvResp{err: err}:
|
||||||
|
case <-ctx.Done():
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Launch as a Windows Service if necessary
|
// Launch as a Windows Service if necessary
|
||||||
if err := launchService(server, done); err != nil {
|
if err := launchService(server, done); err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
server.Stop()
|
||||||
|
case chsrv <- srvResp{s: server}:
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
serverC <- server
|
var server *server.Server
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return ctx.Err()
|
||||||
|
case r := <-chsrv:
|
||||||
|
if r.err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
server = r.s
|
||||||
|
}
|
||||||
|
|
||||||
|
// We don't send the server down serverC directly in the goroutine above because we need it lower down.
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return ctx.Err()
|
||||||
|
case serverC <- server:
|
||||||
|
}
|
||||||
|
|
||||||
if config.Debug.Address != "" {
|
if config.Debug.Address != "" {
|
||||||
var l net.Listener
|
var l net.Listener
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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,13 +54,13 @@ 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()
|
||||||
|
if server != nil {
|
||||||
|
server.Stop()
|
||||||
|
}
|
||||||
close(done)
|
close(done)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
server.Stop()
|
|
||||||
close(done)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
setupDumpStacks()
|
setupDumpStacks()
|
||||||
|
Loading…
Reference in New Issue
Block a user