Calculate base number of tasks.

We was counting all the tasks in a service. It means also shotted down
or rejected tasks. This was getting us a bad started point.
This commit is contained in:
Gianluca Arbezzano 2017-03-14 22:38:43 +00:00
parent 432a6c9355
commit 2a8614aa78
2 changed files with 51 additions and 4 deletions

View File

@ -68,10 +68,11 @@ func (p SwarmProvider) Scale(serviceId string, target int, direction bool) error
spec := service.Spec spec := service.Spec
var ptrFromSystem uint64 var ptrFromSystem uint64
base := p.calculateActiveTasks(tasks)
if direction == true { if direction == true {
ptrFromSystem = uint64(len(tasks) + target) ptrFromSystem = uint64(base + target)
} else { } else {
ptrFromSystem = uint64(len(tasks) - target) ptrFromSystem = uint64(base - target)
} }
spec.Mode.Replicated.Replicas = &ptrFromSystem spec.Mode.Replicated.Replicas = &ptrFromSystem
_, err = p.dockerClient.ServiceUpdate(ctx, serviceId, service.Version, spec, types.ServiceUpdateOptions{}) _, err = p.dockerClient.ServiceUpdate(ctx, serviceId, service.Version, spec, types.ServiceUpdateOptions{})
@ -85,13 +86,34 @@ func (p SwarmProvider) Scale(serviceId string, target int, direction bool) error
logrus.WithFields(logrus.Fields{ logrus.WithFields(logrus.Fields{
"provider": "swarm", "provider": "swarm",
}).Debugf("Service %s scaled.", serviceId) }).Debugf("Service %s scaled from %d to %d", serviceId, base, ptrFromSystem)
return nil return nil
} }
// This function validate if a request is acceptable or not.
func (p *SwarmProvider) isAcceptable(tasks []swarm.Task, target int, direction bool) error { func (p *SwarmProvider) isAcceptable(tasks []swarm.Task, target int, direction bool) error {
if len(tasks) < target && direction == false { if p.calculateActiveTasks(tasks) < target && direction == false {
return errors.New(fmt.Sprintf("I can not scale down because it has only %d running.", target)) return errors.New(fmt.Sprintf("I can not scale down because it has only %d running.", target))
} }
return nil return nil
} }
// Calculate the number of tasks to use as started poit to scale up or down.
// This function is necesarry because we need to exclude shutted down or
// rejected tasks.
func (p *SwarmProvider) calculateActiveTasks(tasks []swarm.Task) int {
c := 0
for _, task := range tasks {
if task.Status.State == swarm.TaskStateNew ||
task.Status.State == swarm.TaskStateAccepted ||
task.Status.State == swarm.TaskStatePending ||
task.Status.State == swarm.TaskStateAssigned ||
task.Status.State == swarm.TaskStateStarting ||
task.Status.State == swarm.TaskStatePreparing ||
task.Status.State == swarm.TaskStateReady ||
task.Status.State == swarm.TaskStateRunning {
c = c + 1
}
}
return c
}

View File

@ -16,3 +16,28 @@ func TestTaskCannotScaleDownBecauseItHasNotEnoughTaskRunning(t *testing.T) {
t.Errorf("It can not scale") t.Errorf("It can not scale")
} }
} }
func TestExcludeUnCountedTasks(t *testing.T) {
p := SwarmProvider{}
tasks := []swarm.Task{
swarm.Task{
Status: swarm.TaskStatus{
State: swarm.TaskStatePreparing,
},
},
swarm.Task{
Status: swarm.TaskStatus{
State: swarm.TaskStateRunning,
},
},
swarm.Task{
Status: swarm.TaskStatus{
State: swarm.TaskStateFailed,
},
},
}
n := p.calculateActiveTasks(tasks)
if n != 2 {
t.Errorf("Tasks need to be two")
}
}