forked from evergreen-ci/evergreen
/
task_priority_cmp.go
146 lines (126 loc) · 4.23 KB
/
task_priority_cmp.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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package scheduler
import (
"github.com/evergreen-ci/evergreen"
"github.com/evergreen-ci/evergreen/model/task"
"github.com/pkg/errors"
)
// Comparator (-1 if second is more important, 1 if first is, 0 if equal)
// takes in the task comparator because it may need access to additional info
// beyond just what's in the tasks
type taskPriorityCmp func(task.Task, task.Task, *CmpBasedTaskComparator) (
int, error)
// Importance comparison functions for tasks. Used to prioritize tasks by the
// CmpBasedTaskComparator.
// byPriority compares the explicit Priority field of the Task documents for
// each Task. The Task whose Priority field is higher will be considered
// more important.
func byPriority(t1, t2 task.Task, comparator *CmpBasedTaskComparator) (int,
error) {
if t1.Priority > t2.Priority {
return 1, nil
}
if t1.Priority < t2.Priority {
return -1, nil
}
return 0, nil
}
// byNumDeps compares the NumDependents field of the Task documents for
// each Task. The Task whose NumDependents field is higher will be considered
// more important.
func byNumDeps(t1, t2 task.Task, comparator *CmpBasedTaskComparator) (int,
error) {
if t1.NumDependents > t2.NumDependents {
return 1, nil
}
if t1.NumDependents < t2.NumDependents {
return -1, nil
}
return 0, nil
}
// byRevisionOrderNumber compares the RevisionOrderNumber fields for the two Tasks,
// and considers the one with the higher RevisionOrderNumber to be more important.
// byRevisionOrderNumber short circuits if the two tasks are not of the same
// project, since RevisionOrderNumber is meaningless across projects.
func byRevisionOrderNumber(t1, t2 task.Task,
comparator *CmpBasedTaskComparator) (int, error) {
if t1.Project != t2.Project {
return 0, nil
}
if t1.RevisionOrderNumber > t2.RevisionOrderNumber {
return 1, nil
}
if t2.RevisionOrderNumber > t1.RevisionOrderNumber {
return -1, nil
}
return 0, nil
}
// byCreateTime compares the CreateTime fields of the two tasks, and considers
// the task with the later CreateTime to be more important. byCreateTime
// short-circuits if the two tasks are from the same project, since
// RevisionOrderNumber is a more reliable indicator on the same project.
func byCreateTime(t1, t2 task.Task, comparator *CmpBasedTaskComparator) (int,
error) {
if t1.Project == t2.Project {
return 0, nil
}
if t1.CreateTime.After(t2.CreateTime) {
return 1, nil
}
if t2.CreateTime.After(t1.CreateTime) {
return -1, nil
}
return 0, nil
}
// byRecentlyFailing compares the results of the previous executions of each
// Task, and considers one more important if its previous execution resulted in
// failure.
func byRecentlyFailing(t1, t2 task.Task,
comparator *CmpBasedTaskComparator) (int, error) {
firstPrev, present := comparator.previousTasksCache[t1.Id]
if !present {
return 0, errors.Errorf("No cached previous task available for task with"+
" id %v", t1.Id)
}
secondPrev, present := comparator.previousTasksCache[t2.Id]
if !present {
return 0, errors.Errorf("No cached previous task available for task with"+
" id %v", t2.Id)
}
if firstPrev.Status == evergreen.TaskFailed &&
secondPrev.Status != evergreen.TaskFailed {
return 1, nil
}
if secondPrev.Status == evergreen.TaskFailed &&
firstPrev.Status != evergreen.TaskFailed {
return -1, nil
}
return 0, nil
}
// bySimilarFailing takes two tasks with the same revision, and considers one
// more important if it has a greater number of failed tasks with the same
// revision, project, display name and requester (but in one or more
// buildvariants) that failed.
func bySimilarFailing(t1, t2 task.Task,
comparator *CmpBasedTaskComparator) (int, error) {
// this comparator only applies to tasks within the same revision
if t1.Revision != t2.Revision {
return 0, nil
}
numSimilarFailingOne, ok := comparator.similarFailingCount[t1.Id]
if !ok {
return 0, errors.Errorf("No similar failing count entry for task with "+
"id %v", t1.Id)
}
numSimilarFailingTwo, ok := comparator.similarFailingCount[t2.Id]
if !ok {
return 0, errors.Errorf("No similar failing count entry for task with "+
"id %v", t2.Id)
}
if numSimilarFailingOne > numSimilarFailingTwo {
return 1, nil
}
if numSimilarFailingOne < numSimilarFailingTwo {
return -1, nil
}
return 0, nil
}