| 472 | } |
| 473 | |
| 474 | func (*globalProgressUpdater) tasksByNode(tasks []swarm.Task) map[string]swarm.Task { |
| 475 | // If there are multiple tasks with the same node ID, favor the one |
| 476 | // with the *lowest* desired state. This can happen in restart |
| 477 | // scenarios. |
| 478 | tasksByNode := make(map[string]swarm.Task) |
| 479 | for _, task := range tasks { |
| 480 | if numberedStates[task.DesiredState] == 0 || numberedStates[task.Status.State] == 0 { |
| 481 | continue |
| 482 | } |
| 483 | if existingTask, ok := tasksByNode[task.NodeID]; ok { |
| 484 | if numberedStates[existingTask.DesiredState] < numberedStates[task.DesiredState] { |
| 485 | continue |
| 486 | } |
| 487 | |
| 488 | // If the desired states match, observed state breaks |
| 489 | // ties. This can happen with the "start first" service |
| 490 | // update mode. |
| 491 | if numberedStates[existingTask.DesiredState] == numberedStates[task.DesiredState] && |
| 492 | numberedStates[existingTask.Status.State] <= numberedStates[task.Status.State] { |
| 493 | continue |
| 494 | } |
| 495 | } |
| 496 | tasksByNode[task.NodeID] = task |
| 497 | } |
| 498 | |
| 499 | return tasksByNode |
| 500 | } |
| 501 | |
| 502 | func (u *globalProgressUpdater) writeTaskProgress(task swarm.Task, nodeCount int) { |
| 503 | if u.done || nodeCount > maxProgressBars { |