2016-06-07 14:28:28 -07:00
|
|
|
package scheduler
|
|
|
|
|
|
|
|
import "github.com/docker/swarmkit/api"
|
|
|
|
|
|
|
|
// NodeInfo contains a node and some additional metadata.
|
|
|
|
type NodeInfo struct {
|
|
|
|
*api.Node
|
2016-09-13 09:28:01 -07:00
|
|
|
Tasks map[string]*api.Task
|
|
|
|
DesiredRunningTasksCount int
|
|
|
|
DesiredRunningTasksCountByService map[string]int
|
|
|
|
AvailableResources api.Resources
|
2016-06-07 14:28:28 -07:00
|
|
|
}
|
|
|
|
|
2016-06-15 22:41:30 -07:00
|
|
|
func newNodeInfo(n *api.Node, tasks map[string]*api.Task, availableResources api.Resources) NodeInfo {
|
2016-06-07 14:28:28 -07:00
|
|
|
nodeInfo := NodeInfo{
|
2016-09-13 09:28:01 -07:00
|
|
|
Node: n,
|
|
|
|
Tasks: make(map[string]*api.Task),
|
|
|
|
DesiredRunningTasksCountByService: make(map[string]int),
|
|
|
|
AvailableResources: availableResources,
|
2016-06-07 14:28:28 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
for _, t := range tasks {
|
|
|
|
nodeInfo.addTask(t)
|
|
|
|
}
|
|
|
|
return nodeInfo
|
|
|
|
}
|
|
|
|
|
2016-09-13 09:28:01 -07:00
|
|
|
// addTask removes a task from nodeInfo if it's tracked there, and returns true
|
|
|
|
// if nodeInfo was modified.
|
2016-06-07 14:28:28 -07:00
|
|
|
func (nodeInfo *NodeInfo) removeTask(t *api.Task) bool {
|
2016-07-05 11:37:26 -04:00
|
|
|
if nodeInfo.Tasks == nil {
|
2016-06-07 14:28:28 -07:00
|
|
|
return false
|
|
|
|
}
|
2016-09-13 09:28:01 -07:00
|
|
|
oldTask, ok := nodeInfo.Tasks[t.ID]
|
|
|
|
if !ok {
|
2016-06-07 14:28:28 -07:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
delete(nodeInfo.Tasks, t.ID)
|
2016-09-13 09:28:01 -07:00
|
|
|
if oldTask.DesiredState == api.TaskStateRunning {
|
|
|
|
nodeInfo.DesiredRunningTasksCount--
|
|
|
|
nodeInfo.DesiredRunningTasksCountByService[t.ServiceID]--
|
|
|
|
}
|
|
|
|
|
2016-06-15 22:41:30 -07:00
|
|
|
reservations := taskReservations(t.Spec)
|
|
|
|
nodeInfo.AvailableResources.MemoryBytes += reservations.MemoryBytes
|
|
|
|
nodeInfo.AvailableResources.NanoCPUs += reservations.NanoCPUs
|
2016-06-07 14:28:28 -07:00
|
|
|
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2016-09-13 09:28:01 -07:00
|
|
|
// addTask adds or updates a task on nodeInfo, and returns true if nodeInfo was
|
|
|
|
// modified.
|
2016-06-07 14:28:28 -07:00
|
|
|
func (nodeInfo *NodeInfo) addTask(t *api.Task) bool {
|
|
|
|
if nodeInfo.Tasks == nil {
|
|
|
|
nodeInfo.Tasks = make(map[string]*api.Task)
|
|
|
|
}
|
2016-09-13 09:28:01 -07:00
|
|
|
if nodeInfo.DesiredRunningTasksCountByService == nil {
|
|
|
|
nodeInfo.DesiredRunningTasksCountByService = make(map[string]int)
|
|
|
|
}
|
|
|
|
|
|
|
|
oldTask, ok := nodeInfo.Tasks[t.ID]
|
|
|
|
if ok {
|
|
|
|
if t.DesiredState == api.TaskStateRunning && oldTask.DesiredState != api.TaskStateRunning {
|
|
|
|
nodeInfo.Tasks[t.ID] = t
|
|
|
|
nodeInfo.DesiredRunningTasksCount++
|
|
|
|
nodeInfo.DesiredRunningTasksCountByService[t.ServiceID]++
|
|
|
|
return true
|
|
|
|
} else if t.DesiredState != api.TaskStateRunning && oldTask.DesiredState == api.TaskStateRunning {
|
|
|
|
nodeInfo.Tasks[t.ID] = t
|
|
|
|
nodeInfo.DesiredRunningTasksCount--
|
|
|
|
nodeInfo.DesiredRunningTasksCountByService[t.ServiceID]--
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
nodeInfo.Tasks[t.ID] = t
|
|
|
|
reservations := taskReservations(t.Spec)
|
|
|
|
nodeInfo.AvailableResources.MemoryBytes -= reservations.MemoryBytes
|
|
|
|
nodeInfo.AvailableResources.NanoCPUs -= reservations.NanoCPUs
|
|
|
|
|
|
|
|
if t.DesiredState == api.TaskStateRunning {
|
|
|
|
nodeInfo.DesiredRunningTasksCount++
|
|
|
|
nodeInfo.DesiredRunningTasksCountByService[t.ServiceID]++
|
2016-06-07 14:28:28 -07:00
|
|
|
}
|
|
|
|
|
2016-09-13 09:28:01 -07:00
|
|
|
return true
|
2016-06-07 14:28:28 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
func taskReservations(spec api.TaskSpec) (reservations api.Resources) {
|
|
|
|
if spec.Resources != nil && spec.Resources.Reservations != nil {
|
|
|
|
reservations = *spec.Resources.Reservations
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|