|
@@ -16,14 +16,14 @@ const (
|
|
|
// RestartManager defines object that controls container restarting rules.
|
|
|
type RestartManager interface {
|
|
|
Cancel() error
|
|
|
- ShouldRestart(exitCode uint32) (bool, chan error, error)
|
|
|
+ ShouldRestart(exitCode uint32, hasBeenManuallyStopped bool) (bool, chan error, error)
|
|
|
}
|
|
|
|
|
|
type restartManager struct {
|
|
|
sync.Mutex
|
|
|
sync.Once
|
|
|
policy container.RestartPolicy
|
|
|
- failureCount int
|
|
|
+ restartCount int
|
|
|
timeout time.Duration
|
|
|
active bool
|
|
|
cancel chan struct{}
|
|
@@ -31,8 +31,8 @@ type restartManager struct {
|
|
|
}
|
|
|
|
|
|
// New returns a new restartmanager based on a policy.
|
|
|
-func New(policy container.RestartPolicy) RestartManager {
|
|
|
- return &restartManager{policy: policy, cancel: make(chan struct{})}
|
|
|
+func New(policy container.RestartPolicy, restartCount int) RestartManager {
|
|
|
+ return &restartManager{policy: policy, restartCount: restartCount, cancel: make(chan struct{})}
|
|
|
}
|
|
|
|
|
|
func (rm *restartManager) SetPolicy(policy container.RestartPolicy) {
|
|
@@ -41,7 +41,7 @@ func (rm *restartManager) SetPolicy(policy container.RestartPolicy) {
|
|
|
rm.Unlock()
|
|
|
}
|
|
|
|
|
|
-func (rm *restartManager) ShouldRestart(exitCode uint32) (bool, chan error, error) {
|
|
|
+func (rm *restartManager) ShouldRestart(exitCode uint32, hasBeenManuallyStopped bool) (bool, chan error, error) {
|
|
|
rm.Lock()
|
|
|
unlockOnExit := true
|
|
|
defer func() {
|
|
@@ -58,12 +58,6 @@ func (rm *restartManager) ShouldRestart(exitCode uint32) (bool, chan error, erro
|
|
|
return false, nil, fmt.Errorf("invalid call on active restartmanager")
|
|
|
}
|
|
|
|
|
|
- if exitCode != 0 {
|
|
|
- rm.failureCount++
|
|
|
- } else {
|
|
|
- rm.failureCount = 0
|
|
|
- }
|
|
|
-
|
|
|
if rm.timeout == 0 {
|
|
|
rm.timeout = defaultTimeout
|
|
|
} else {
|
|
@@ -72,11 +66,13 @@ func (rm *restartManager) ShouldRestart(exitCode uint32) (bool, chan error, erro
|
|
|
|
|
|
var restart bool
|
|
|
switch {
|
|
|
- case rm.policy.IsAlways(), rm.policy.IsUnlessStopped():
|
|
|
+ case rm.policy.IsAlways():
|
|
|
+ restart = true
|
|
|
+ case rm.policy.IsUnlessStopped() && !hasBeenManuallyStopped:
|
|
|
restart = true
|
|
|
case rm.policy.IsOnFailure():
|
|
|
// the default value of 0 for MaximumRetryCount means that we will not enforce a maximum count
|
|
|
- if max := rm.policy.MaximumRetryCount; max == 0 || rm.failureCount <= max {
|
|
|
+ if max := rm.policy.MaximumRetryCount; max == 0 || rm.restartCount < max {
|
|
|
restart = exitCode != 0
|
|
|
}
|
|
|
}
|
|
@@ -86,6 +82,8 @@ func (rm *restartManager) ShouldRestart(exitCode uint32) (bool, chan error, erro
|
|
|
return false, nil, nil
|
|
|
}
|
|
|
|
|
|
+ rm.restartCount++
|
|
|
+
|
|
|
unlockOnExit = false
|
|
|
rm.active = true
|
|
|
rm.Unlock()
|