/
setup_funcs.go
86 lines (73 loc) · 2.09 KB
/
setup_funcs.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package scheduler
import (
"fmt"
"runtime"
"sort"
"sync"
"github.com/evergreen-ci/evergreen/model/task"
"github.com/pkg/errors"
)
// Function run before sorting all the tasks. Used to fetch and store
// information needed for prioritizing the tasks.
type sortSetupFunc func(comparator *CmpBasedTaskComparator) error
// PopulateCaches runs setup functions and is used by the new/tunable
// scheduler to reprocess tasks before running the new planner.
func PopulateCaches(id string, tasks []task.Task) ([]task.Task, error) {
cmp := &CmpBasedTaskComparator{
tasks: tasks,
runtimeID: id,
setupFuncs: []sortSetupFunc{
cacheExpectedDurations,
},
}
if err := cmp.setupForSortingTasks(); err != nil {
return nil, errors.WithStack(err)
}
return cmp.tasks, nil
}
func cacheExpectedDurations(comparator *CmpBasedTaskComparator) error {
work := make(chan task.Task, len(comparator.tasks))
output := make(chan task.Task, len(comparator.tasks))
for _, t := range comparator.tasks {
work <- t
}
close(work)
wg := &sync.WaitGroup{}
for i := 0; i < runtime.NumCPU(); i++ {
wg.Add(1)
go func() {
defer wg.Done()
for t := range work {
_ = t.FetchExpectedDuration()
output <- t
}
}()
}
wg.Wait()
close(output)
tasks := make([]task.Task, 0, len(comparator.tasks))
for t := range output {
tasks = append(tasks, t)
}
comparator.tasks = tasks
return nil
}
// groupTaskGroups puts tasks that have the same build and task group next to
// each other in the queue. This ensures that, in a stable sort,
// byTaskGroupOrder sorts task group members relative to each other.
func groupTaskGroups(comparator *CmpBasedTaskComparator) error {
taskMap := make(map[string]task.Task)
taskKeys := []string{}
for _, t := range comparator.tasks {
k := fmt.Sprintf("%s-%s-%s", t.BuildId, t.TaskGroup, t.Id)
taskMap[k] = t
taskKeys = append(taskKeys, k)
}
// Reverse sort to sort task groups to the top, so that they are more
// quickly pinned to hosts.
sort.Sort(sort.Reverse(sort.StringSlice(taskKeys)))
for i, k := range taskKeys {
comparator.tasks[i] = taskMap[k]
}
return nil
}