github.com/billybanfield/evergreen@v0.0.0-20170525200750-eeee692790f7/scheduler/task_priority_cmp.go (about) 1 package scheduler 2 3 import ( 4 "github.com/evergreen-ci/evergreen" 5 "github.com/evergreen-ci/evergreen/model/task" 6 "github.com/pkg/errors" 7 ) 8 9 // Comparator (-1 if second is more important, 1 if first is, 0 if equal) 10 // takes in the task comparator because it may need access to additional info 11 // beyond just what's in the tasks 12 type taskPriorityCmp func(task.Task, task.Task, *CmpBasedTaskComparator) ( 13 int, error) 14 15 // Importance comparison functions for tasks. Used to prioritize tasks by the 16 // CmpBasedTaskComparator. 17 18 // byPriority compares the explicit Priority field of the Task documents for 19 // each Task. The Task whose Priority field is higher will be considered 20 // more important. 21 func byPriority(t1, t2 task.Task, comparator *CmpBasedTaskComparator) (int, 22 error) { 23 if t1.Priority > t2.Priority { 24 return 1, nil 25 } 26 if t1.Priority < t2.Priority { 27 return -1, nil 28 } 29 30 return 0, nil 31 } 32 33 // byNumDeps compares the NumDependents field of the Task documents for 34 // each Task. The Task whose NumDependents field is higher will be considered 35 // more important. 36 func byNumDeps(t1, t2 task.Task, comparator *CmpBasedTaskComparator) (int, 37 error) { 38 if t1.NumDependents > t2.NumDependents { 39 return 1, nil 40 } 41 if t1.NumDependents < t2.NumDependents { 42 return -1, nil 43 } 44 45 return 0, nil 46 } 47 48 // byRevisionOrderNumber compares the RevisionOrderNumber fields for the two Tasks, 49 // and considers the one with the higher RevisionOrderNumber to be more important. 50 // byRevisionOrderNumber short circuits if the two tasks are not of the same 51 // project, since RevisionOrderNumber is meaningless across projects. 52 func byRevisionOrderNumber(t1, t2 task.Task, 53 comparator *CmpBasedTaskComparator) (int, error) { 54 55 if t1.Project != t2.Project { 56 return 0, nil 57 } 58 if t1.RevisionOrderNumber > t2.RevisionOrderNumber { 59 return 1, nil 60 } 61 if t2.RevisionOrderNumber > t1.RevisionOrderNumber { 62 return -1, nil 63 } 64 return 0, nil 65 } 66 67 // byCreateTime compares the CreateTime fields of the two tasks, and considers 68 // the task with the later CreateTime to be more important. byCreateTime 69 // short-circuits if the two tasks are from the same project, since 70 // RevisionOrderNumber is a more reliable indicator on the same project. 71 func byCreateTime(t1, t2 task.Task, comparator *CmpBasedTaskComparator) (int, 72 error) { 73 74 if t1.Project == t2.Project { 75 return 0, nil 76 } 77 78 if t1.CreateTime.After(t2.CreateTime) { 79 return 1, nil 80 } 81 if t2.CreateTime.After(t1.CreateTime) { 82 return -1, nil 83 } 84 return 0, nil 85 } 86 87 // byRecentlyFailing compares the results of the previous executions of each 88 // Task, and considers one more important if its previous execution resulted in 89 // failure. 90 func byRecentlyFailing(t1, t2 task.Task, 91 comparator *CmpBasedTaskComparator) (int, error) { 92 firstPrev, present := comparator.previousTasksCache[t1.Id] 93 if !present { 94 return 0, errors.Errorf("No cached previous task available for task with"+ 95 " id %v", t1.Id) 96 } 97 secondPrev, present := comparator.previousTasksCache[t2.Id] 98 if !present { 99 return 0, errors.Errorf("No cached previous task available for task with"+ 100 " id %v", t2.Id) 101 } 102 103 if firstPrev.Status == evergreen.TaskFailed && 104 secondPrev.Status != evergreen.TaskFailed { 105 return 1, nil 106 } 107 if secondPrev.Status == evergreen.TaskFailed && 108 firstPrev.Status != evergreen.TaskFailed { 109 return -1, nil 110 } 111 112 return 0, nil 113 } 114 115 // bySimilarFailing takes two tasks with the same revision, and considers one 116 // more important if it has a greater number of failed tasks with the same 117 // revision, project, display name and requester (but in one or more 118 // buildvariants) that failed. 119 func bySimilarFailing(t1, t2 task.Task, 120 comparator *CmpBasedTaskComparator) (int, error) { 121 // this comparator only applies to tasks within the same revision 122 if t1.Revision != t2.Revision { 123 return 0, nil 124 } 125 126 numSimilarFailingOne, ok := comparator.similarFailingCount[t1.Id] 127 if !ok { 128 return 0, errors.Errorf("No similar failing count entry for task with "+ 129 "id %v", t1.Id) 130 } 131 132 numSimilarFailingTwo, ok := comparator.similarFailingCount[t2.Id] 133 if !ok { 134 return 0, errors.Errorf("No similar failing count entry for task with "+ 135 "id %v", t2.Id) 136 } 137 138 if numSimilarFailingOne > numSimilarFailingTwo { 139 return 1, nil 140 } 141 142 if numSimilarFailingOne < numSimilarFailingTwo { 143 return -1, nil 144 } 145 return 0, nil 146 }