Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
| ... | ... |
@@ -104,7 +104,7 @@ github.com/docker/containerd 422e31ce907fd9c3833a38d7b8fdd023e5a76e73 |
| 104 | 104 |
github.com/tonistiigi/fifo 1405643975692217d6720f8b54aeee1bf2cd5cf4 |
| 105 | 105 |
|
| 106 | 106 |
# cluster |
| 107 |
-github.com/docker/swarmkit 0e2d9ebcea9d5bbd4a06b3b964fb96356801f880 |
|
| 107 |
+github.com/docker/swarmkit d316a73f803e9eb75e3daa7e0f846017b0c9a145 |
|
| 108 | 108 |
github.com/golang/mock bd3c8e81be01eef76d4b503f5e687d2d1354d2d9 |
| 109 | 109 |
github.com/gogo/protobuf 8d70fb3182befc465c4a1eac8ad4d38ff49778e2 |
| 110 | 110 |
github.com/cloudflare/cfssl 7fb22c8cba7ecaf98e4082d22d65800cf45e042a |
| ... | ... |
@@ -111,6 +111,10 @@ func (ns *nodeSet) tree(serviceID string, preferences []*api.PlacementPreference |
| 111 | 111 |
tree = next |
| 112 | 112 |
} |
| 113 | 113 |
|
| 114 |
+ if node.ActiveTasksCountByService != nil {
|
|
| 115 |
+ tree.tasks += node.ActiveTasksCountByService[serviceID] |
|
| 116 |
+ } |
|
| 117 |
+ |
|
| 114 | 118 |
if tree.nodeHeap.lessFunc == nil {
|
| 115 | 119 |
tree.nodeHeap.lessFunc = nodeLess |
| 116 | 120 |
} |
| ... | ... |
@@ -1,7 +1,6 @@ |
| 1 | 1 |
package scheduler |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
- "container/list" |
|
| 5 | 4 |
"time" |
| 6 | 5 |
|
| 7 | 6 |
"github.com/docker/swarmkit/api" |
| ... | ... |
@@ -30,7 +29,7 @@ type schedulingDecision struct {
|
| 30 | 30 |
// Scheduler assigns tasks to nodes. |
| 31 | 31 |
type Scheduler struct {
|
| 32 | 32 |
store *store.MemoryStore |
| 33 |
- unassignedTasks *list.List |
|
| 33 |
+ unassignedTasks map[string]*api.Task |
|
| 34 | 34 |
// preassignedTasks already have NodeID, need resource validation |
| 35 | 35 |
preassignedTasks map[string]*api.Task |
| 36 | 36 |
nodeSet nodeSet |
| ... | ... |
@@ -47,7 +46,7 @@ type Scheduler struct {
|
| 47 | 47 |
func New(store *store.MemoryStore) *Scheduler {
|
| 48 | 48 |
return &Scheduler{
|
| 49 | 49 |
store: store, |
| 50 |
- unassignedTasks: list.New(), |
|
| 50 |
+ unassignedTasks: make(map[string]*api.Task), |
|
| 51 | 51 |
preassignedTasks: make(map[string]*api.Task), |
| 52 | 52 |
allTasks: make(map[string]*api.Task), |
| 53 | 53 |
stopChan: make(chan struct{}),
|
| ... | ... |
@@ -191,7 +190,7 @@ func (s *Scheduler) Stop() {
|
| 191 | 191 |
|
| 192 | 192 |
// enqueue queues a task for scheduling. |
| 193 | 193 |
func (s *Scheduler) enqueue(t *api.Task) {
|
| 194 |
- s.unassignedTasks.PushBack(t) |
|
| 194 |
+ s.unassignedTasks[t.ID] = t |
|
| 195 | 195 |
} |
| 196 | 196 |
|
| 197 | 197 |
func (s *Scheduler) createTask(ctx context.Context, t *api.Task) int {
|
| ... | ... |
@@ -333,15 +332,12 @@ func (s *Scheduler) processPreassignedTasks(ctx context.Context) {
|
| 333 | 333 |
// tick attempts to schedule the queue. |
| 334 | 334 |
func (s *Scheduler) tick(ctx context.Context) {
|
| 335 | 335 |
tasksByCommonSpec := make(map[string]map[string]*api.Task) |
| 336 |
- schedulingDecisions := make(map[string]schedulingDecision, s.unassignedTasks.Len()) |
|
| 336 |
+ schedulingDecisions := make(map[string]schedulingDecision, len(s.unassignedTasks)) |
|
| 337 | 337 |
|
| 338 |
- var next *list.Element |
|
| 339 |
- for e := s.unassignedTasks.Front(); e != nil; e = next {
|
|
| 340 |
- next = e.Next() |
|
| 341 |
- t := s.allTasks[e.Value.(*api.Task).ID] |
|
| 338 |
+ for taskID, t := range s.unassignedTasks {
|
|
| 342 | 339 |
if t == nil || t.NodeID != "" {
|
| 343 | 340 |
// task deleted or already assigned |
| 344 |
- s.unassignedTasks.Remove(e) |
|
| 341 |
+ delete(s.unassignedTasks, taskID) |
|
| 345 | 342 |
continue |
| 346 | 343 |
} |
| 347 | 344 |
|
| ... | ... |
@@ -362,8 +358,8 @@ func (s *Scheduler) tick(ctx context.Context) {
|
| 362 | 362 |
if tasksByCommonSpec[taskGroupKey] == nil {
|
| 363 | 363 |
tasksByCommonSpec[taskGroupKey] = make(map[string]*api.Task) |
| 364 | 364 |
} |
| 365 |
- tasksByCommonSpec[taskGroupKey][t.ID] = t |
|
| 366 |
- s.unassignedTasks.Remove(e) |
|
| 365 |
+ tasksByCommonSpec[taskGroupKey][taskID] = t |
|
| 366 |
+ delete(s.unassignedTasks, taskID) |
|
| 367 | 367 |
} |
| 368 | 368 |
|
| 369 | 369 |
for _, taskGroup := range tasksByCommonSpec {
|
| ... | ... |
@@ -602,6 +598,12 @@ func (s *Scheduler) scheduleNTasksOnNodes(ctx context.Context, n int, taskGroup |
| 602 | 602 |
nodeIter := 0 |
| 603 | 603 |
nodeCount := len(nodes) |
| 604 | 604 |
for taskID, t := range taskGroup {
|
| 605 |
+ // Skip tasks which were already scheduled because they ended |
|
| 606 |
+ // up in two groups at once. |
|
| 607 |
+ if _, exists := schedulingDecisions[taskID]; exists {
|
|
| 608 |
+ continue |
|
| 609 |
+ } |
|
| 610 |
+ |
|
| 605 | 611 |
node := &nodes[nodeIter%nodeCount] |
| 606 | 612 |
|
| 607 | 613 |
log.G(ctx).WithField("task.id", t.ID).Debugf("assigning to node %s", node.ID)
|