diff options
author | Josh Hawn <josh.hawn@docker.com> | 2017-03-30 13:52:40 -0700 |
---|---|---|
committer | Josh Hawn <josh.hawn@docker.com> | 2017-05-16 15:09:14 -0700 |
commit | cfdf84d5d04c8ee656e5c4ad3db993c258e52674 (patch) | |
tree | bef44fcea8cce53e22286437fdb550f6e9fa06ca /daemon/stop.go | |
parent | 1290ec2d4b3611293cd993cd12fd9e78e268e296 (diff) | |
download | docker-cfdf84d5d04c8ee656e5c4ad3db993c258e52674.tar.gz |
Update Container Wait Backend
This patch consolidates the two WaitStop and WaitWithContext methods
on the container.State type. Now there is a single method, Wait, which
takes a context and a bool specifying whether to wait for not just a
container exit but also removal.
The behavior has been changed slightly so that a wait call during a
Created state will not return immediately but instead wait for the
container to be started and then exited.
The interface has been changed to no longer block, but instead returns
a channel on which the caller can receive a *StateStatus value which
indicates the ExitCode or an error if there was one (like a context
timeout or state transition error).
These changes have been propagated through the rest of the deamon to
preserve all other existing behavior.
Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn)
Diffstat (limited to 'daemon/stop.go')
-rw-r--r-- | daemon/stop.go | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/daemon/stop.go b/daemon/stop.go index a17e8c8dde..4fd1e40c1e 100644 --- a/daemon/stop.go +++ b/daemon/stop.go @@ -1,6 +1,7 @@ package daemon import ( + "context" "fmt" "net/http" "time" @@ -60,7 +61,10 @@ func (daemon *Daemon) containerStop(container *container.Container, seconds int) // So, instead we'll give it up to 2 more seconds to complete and if // by that time the container is still running, then the error // we got is probably valid and so we force kill it. - if _, err := container.WaitStop(2 * time.Second); err != nil { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + defer cancel() + + if status := <-container.Wait(ctx, false); status.Err() != nil { logrus.Infof("Container failed to stop after sending signal %d to the process, force killing", stopSignal) if err := daemon.killPossiblyDeadProcess(container, 9); err != nil { return err @@ -69,11 +73,15 @@ func (daemon *Daemon) containerStop(container *container.Container, seconds int) } // 2. Wait for the process to exit on its own - if _, err := container.WaitStop(time.Duration(seconds) * time.Second); err != nil { + ctx, cancel := context.WithTimeout(context.Background(), time.Duration(seconds)*time.Second) + defer cancel() + + if status := <-container.Wait(ctx, false); status.Err() != nil { logrus.Infof("Container %v failed to exit within %d seconds of signal %d - using the force", container.ID, seconds, stopSignal) // 3. If it doesn't, then send SIGKILL if err := daemon.Kill(container); err != nil { - container.WaitStop(-1 * time.Second) + // Wait without a timeout, ignore result. + _ = <-container.Wait(context.Background(), false) logrus.Warn(err) // Don't return error because we only care that container is stopped, not what function stopped it } } |