Skip to content

Commit b6db56b

Browse files
committed
Reset restart timeout if execution longer than 10s
Restore the 1.10 logic that will reset the restart manager's timeout or backoff delay if a container executes longer than 10s reguardless of exit status or policy. Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
1 parent a403078 commit b6db56b

File tree

6 files changed

+48
-7
lines changed

6 files changed

+48
-7
lines changed

container/container.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,7 @@ func copyEscapable(dst io.Writer, src io.ReadCloser, keys []byte) (written int64
519519
// ShouldRestart decides whether the daemon should restart the container or not.
520520
// This is based on the container's restart policy.
521521
func (container *Container) ShouldRestart() bool {
522-
shouldRestart, _, _ := container.restartManager.ShouldRestart(uint32(container.ExitCode), container.HasBeenManuallyStopped)
522+
shouldRestart, _, _ := container.restartManager.ShouldRestart(uint32(container.ExitCode), container.HasBeenManuallyStopped, container.FinishedAt.Sub(container.StartedAt))
523523
return shouldRestart
524524
}
525525

libcontainerd/container.go

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package libcontainerd
22

33
import (
44
"fmt"
5+
"time"
56

67
"github.com/docker/docker/restartmanager"
78
)
@@ -18,6 +19,7 @@ type containerCommon struct {
1819
restartManager restartmanager.RestartManager
1920
restarting bool
2021
processes map[string]*process
22+
startedAt time.Time
2123
}
2224

2325
// WithRestartManager sets the restartmanager to be used with the container.

libcontainerd/container_linux.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"os"
77
"path/filepath"
88
"syscall"
9+
"time"
910

1011
"github.com/Sirupsen/logrus"
1112
containerd "github.com/docker/containerd/api/grpc/types"
@@ -74,6 +75,7 @@ func (ctr *container) start() error {
7475
ctr.closeFifos(iopipe)
7576
return err
7677
}
78+
ctr.startedAt = time.Now()
7779

7880
if err := ctr.client.backend.AttachStreams(ctr.containerID, *iopipe); err != nil {
7981
return err
@@ -118,7 +120,7 @@ func (ctr *container) handleEvent(e *containerd.Event) error {
118120
st.State = StateExitProcess
119121
}
120122
if st.State == StateExit && ctr.restartManager != nil {
121-
restart, wait, err := ctr.restartManager.ShouldRestart(e.Status, false)
123+
restart, wait, err := ctr.restartManager.ShouldRestart(e.Status, false, time.Since(ctr.startedAt))
122124
if err != nil {
123125
logrus.Warnf("container %s %v", ctr.containerID, err)
124126
} else if restart {

libcontainerd/container_windows.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"io"
55
"strings"
66
"syscall"
7+
"time"
78

89
"github.com/Microsoft/hcsshim"
910
"github.com/Sirupsen/logrus"
@@ -78,6 +79,7 @@ func (ctr *container) start() error {
7879
}
7980
return err
8081
}
82+
ctr.startedAt = time.Now()
8183

8284
// Convert io.ReadClosers to io.Readers
8385
if stdout != nil {
@@ -168,7 +170,7 @@ func (ctr *container) waitExit(pid uint32, processFriendlyName string, isFirstPr
168170
}
169171

170172
if si.State == StateExit && ctr.restartManager != nil {
171-
restart, wait, err := ctr.restartManager.ShouldRestart(uint32(exitCode), false)
173+
restart, wait, err := ctr.restartManager.ShouldRestart(uint32(exitCode), false, time.Since(ctr.startedAt))
172174
if err != nil {
173175
logrus.Error(err)
174176
} else if restart {

restartmanager/restartmanager.go

+7-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const (
1616
// RestartManager defines object that controls container restarting rules.
1717
type RestartManager interface {
1818
Cancel() error
19-
ShouldRestart(exitCode uint32, hasBeenManuallyStopped bool) (bool, chan error, error)
19+
ShouldRestart(exitCode uint32, hasBeenManuallyStopped bool, executionDuration time.Duration) (bool, chan error, error)
2020
}
2121

2222
type restartManager struct {
@@ -41,7 +41,7 @@ func (rm *restartManager) SetPolicy(policy container.RestartPolicy) {
4141
rm.Unlock()
4242
}
4343

44-
func (rm *restartManager) ShouldRestart(exitCode uint32, hasBeenManuallyStopped bool) (bool, chan error, error) {
44+
func (rm *restartManager) ShouldRestart(exitCode uint32, hasBeenManuallyStopped bool, executionDuration time.Duration) (bool, chan error, error) {
4545
if rm.policy.IsNone() {
4646
return false, nil, nil
4747
}
@@ -60,7 +60,11 @@ func (rm *restartManager) ShouldRestart(exitCode uint32, hasBeenManuallyStopped
6060
if rm.active {
6161
return false, nil, fmt.Errorf("invalid call on active restartmanager")
6262
}
63-
63+
// if the container ran for more than 10s, reguardless of status and policy reset the
64+
// the timeout back to the default.
65+
if executionDuration.Seconds() >= 10 {
66+
rm.timeout = 0
67+
}
6468
if rm.timeout == 0 {
6569
rm.timeout = defaultTimeout
6670
} else {

restartmanager/restartmanager_test.go

+32-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,34 @@
11
package restartmanager
22

3-
// FIXME
3+
import (
4+
"testing"
5+
"time"
6+
7+
"github.com/docker/engine-api/types/container"
8+
)
9+
10+
func TestRestartManagerTimeout(t *testing.T) {
11+
rm := New(container.RestartPolicy{Name: "always"}, 0).(*restartManager)
12+
should, _, err := rm.ShouldRestart(0, false, 1*time.Second)
13+
if err != nil {
14+
t.Fatal(err)
15+
}
16+
if !should {
17+
t.Fatal("container should be restarted")
18+
}
19+
if rm.timeout != 100*time.Millisecond {
20+
t.Fatalf("restart manager should have a timeout of 100ms but has %s", rm.timeout)
21+
}
22+
}
23+
24+
func TestRestartManagerTimeoutReset(t *testing.T) {
25+
rm := New(container.RestartPolicy{Name: "always"}, 0).(*restartManager)
26+
rm.timeout = 5 * time.Second
27+
_, _, err := rm.ShouldRestart(0, false, 10*time.Second)
28+
if err != nil {
29+
t.Fatal(err)
30+
}
31+
if rm.timeout != 100*time.Millisecond {
32+
t.Fatalf("restart manager should have a timeout of 100ms but has %s", rm.timeout)
33+
}
34+
}

0 commit comments

Comments
 (0)