mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Improve wait during restart
We need to do this so that when a user asks docker to stop the container and it is currently in the restart loop we don't want to have to wait for the duration of the restart time increment before ack. the stop. Signed-off-by: Michael Crosby <michael@docker.com>
This commit is contained in:
parent
c4a00d549d
commit
972c894931
1 changed files with 41 additions and 9 deletions
|
@ -35,6 +35,11 @@ type containerMonitor struct {
|
|||
// either because docker or the user asked for the container to be stopped
|
||||
shouldStop bool
|
||||
|
||||
// stopChan is used to signal to the monitor whenever there is a wait for the
|
||||
// next restart so that the timeIncrement is not honored and the user is not
|
||||
// left waiting for nothing to happen during this time
|
||||
stopChan chan struct{}
|
||||
|
||||
// timeIncrement is the amount of time to wait between restarts
|
||||
// this is in milliseconds
|
||||
timeIncrement int
|
||||
|
@ -45,6 +50,7 @@ func newContainerMonitor(container *Container, policy runconfig.RestartPolicy) *
|
|||
container: container,
|
||||
restartPolicy: policy,
|
||||
timeIncrement: defaultTimeIncrement,
|
||||
stopChan: make(chan struct{}, 1),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,7 +58,14 @@ func newContainerMonitor(container *Container, policy runconfig.RestartPolicy) *
|
|||
// for exits the next time the process dies
|
||||
func (m *containerMonitor) ExitOnNext() {
|
||||
m.mux.Lock()
|
||||
m.shouldStop = true
|
||||
|
||||
// we need to protect having a double close of the channel when stop is called
|
||||
// twice or else we will get a panic
|
||||
if !m.shouldStop {
|
||||
m.shouldStop = true
|
||||
close(m.stopChan)
|
||||
}
|
||||
|
||||
m.mux.Unlock()
|
||||
}
|
||||
|
||||
|
@ -87,7 +100,7 @@ func (m *containerMonitor) Start() error {
|
|||
// reset the restart count
|
||||
m.container.RestartCount = -1
|
||||
|
||||
for !m.shouldStop {
|
||||
for {
|
||||
m.container.RestartCount++
|
||||
|
||||
if err := m.container.startLoggingToDisk(); err != nil {
|
||||
|
@ -109,22 +122,34 @@ func (m *containerMonitor) Start() error {
|
|||
if m.shouldRestart(exitStatus) {
|
||||
m.container.State.SetRestarting(exitStatus)
|
||||
|
||||
m.container.LogEvent("die")
|
||||
|
||||
m.resetContainer()
|
||||
|
||||
// sleep with a small time increment between each restart to help avoid issues cased by quickly
|
||||
// restarting the container because of some types of errors ( networking cut out, etc... )
|
||||
time.Sleep(time.Duration(m.timeIncrement) * time.Millisecond)
|
||||
m.waitForNextRestart()
|
||||
|
||||
// we need to check this before reentering the loop because the waitForNextRestart could have
|
||||
// been terminated by a request from a user
|
||||
if m.shouldStop {
|
||||
m.container.State.SetStopped(exitStatus)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
m.container.State.SetStopped(exitStatus)
|
||||
|
||||
m.container.LogEvent("die")
|
||||
|
||||
m.resetContainer()
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
m.container.State.SetStopped(exitStatus)
|
||||
|
||||
m.resetContainer()
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -145,6 +170,15 @@ func (m *containerMonitor) resetMonitor(successful bool) {
|
|||
}
|
||||
}
|
||||
|
||||
// waitForNextRestart waits with the default time increment to restart the container unless
|
||||
// a user or docker asks to container to be stopped
|
||||
func (m *containerMonitor) waitForNextRestart() {
|
||||
select {
|
||||
case <-time.After(time.Duration(m.timeIncrement) * time.Millisecond):
|
||||
case <-m.stopChan:
|
||||
}
|
||||
}
|
||||
|
||||
// shouldRestart checks the restart policy and applies the rules to determine if
|
||||
// the container's process should be restarted
|
||||
func (m *containerMonitor) shouldRestart(exitStatus int) bool {
|
||||
|
@ -221,8 +255,6 @@ func (m *containerMonitor) resetContainer() {
|
|||
container.stdin, container.stdinPipe = io.Pipe()
|
||||
}
|
||||
|
||||
container.LogEvent("die")
|
||||
|
||||
c := container.command.Cmd
|
||||
|
||||
container.command.Cmd = exec.Cmd{
|
||||
|
|
Loading…
Add table
Reference in a new issue