OLD | NEW |
| (Empty) |
1 package task_scheduler | |
2 | |
3 import ( | |
4 "fmt" | |
5 "path" | |
6 "strings" | |
7 | |
8 swarming_api "github.com/luci/luci-go/common/api/swarming/swarming/v1" | |
9 "go.skia.org/infra/build_scheduler/go/db" | |
10 "go.skia.org/infra/go/isolate" | |
11 "go.skia.org/infra/go/swarming" | |
12 ) | |
13 | |
14 // taskCandidate is a struct used for determining which tasks to schedule. | |
15 type taskCandidate struct { | |
16 Commits []string | |
17 IsolatedInput string | |
18 IsolatedHashes []string | |
19 Name string | |
20 Repo string | |
21 Revision string | |
22 Score float64 | |
23 StealingFromId string | |
24 TaskSpec *TaskSpec | |
25 } | |
26 | |
27 // Copy returns a copy of the taskCandidate. | |
28 func (c *taskCandidate) Copy() *taskCandidate { | |
29 commits := make([]string, len(c.Commits)) | |
30 copy(commits, c.Commits) | |
31 isolatedHashes := make([]string, len(c.IsolatedHashes)) | |
32 copy(isolatedHashes, c.IsolatedHashes) | |
33 return &taskCandidate{ | |
34 Commits: commits, | |
35 IsolatedInput: c.IsolatedInput, | |
36 IsolatedHashes: isolatedHashes, | |
37 Name: c.Name, | |
38 Repo: c.Repo, | |
39 Revision: c.Revision, | |
40 Score: c.Score, | |
41 StealingFromId: c.StealingFromId, | |
42 TaskSpec: c.TaskSpec.Copy(), | |
43 } | |
44 } | |
45 | |
46 // MakeId generates a string ID for the taskCandidate. | |
47 func (c *taskCandidate) MakeId() string { | |
48 return fmt.Sprintf("taskCandidate|%s|%s|%s", c.Repo, c.Name, c.Revision) | |
49 } | |
50 | |
51 // ParseId generates taskCandidate information from the ID. | |
52 func parseId(id string) (string, string, string, error) { | |
53 split := strings.Split(id, "|") | |
54 if len(split) != 4 { | |
55 return "", "", "", fmt.Errorf("Invalid ID: %q", id) | |
56 } | |
57 if split[0] != "taskCandidate" { | |
58 return "", "", "", fmt.Errorf("Invalid ID: %q", id) | |
59 } | |
60 for _, s := range split[1:] { | |
61 if s == "" { | |
62 return "", "", "", fmt.Errorf("Invalid ID: %q", id) | |
63 } | |
64 } | |
65 return split[1], split[2], split[3], nil | |
66 } | |
67 | |
68 // MakeTask instantiates a db.Task from the taskCandidate. | |
69 func (c *taskCandidate) MakeTask() *db.Task { | |
70 commits := make([]string, len(c.Commits)) | |
71 copy(commits, c.Commits) | |
72 return &db.Task{ | |
73 Commits: commits, | |
74 Id: "", // Filled in when the task is inserted into the DB
. | |
75 Name: c.Name, | |
76 Repo: c.Repo, | |
77 Revision: c.Revision, | |
78 } | |
79 } | |
80 | |
81 // MakeIsolateTask creates an isolate.Task from this taskCandidate. | |
82 func (c *taskCandidate) MakeIsolateTask(infraBotsDir, baseDir string) *isolate.T
ask { | |
83 return &isolate.Task{ | |
84 BaseDir: baseDir, | |
85 Blacklist: isolate.DEFAULT_BLACKLIST, | |
86 Deps: c.IsolatedHashes, | |
87 IsolateFile: path.Join(infraBotsDir, c.TaskSpec.Isolate), | |
88 OsType: "linux", // TODO(borenet) | |
89 } | |
90 } | |
91 | |
92 // MakeTaskRequest creates a SwarmingRpcsNewTaskRequest object from the taskCand
idate. | |
93 func (c *taskCandidate) MakeTaskRequest(id string) *swarming_api.SwarmingRpcsNew
TaskRequest { | |
94 cipdPackages := make([]*swarming_api.SwarmingRpcsCipdPackage, 0, len(c.T
askSpec.CipdPackages)) | |
95 for _, p := range c.TaskSpec.CipdPackages { | |
96 cipdPackages = append(cipdPackages, &swarming_api.SwarmingRpcsCi
pdPackage{ | |
97 PackageName: p.Name, | |
98 Path: p.Path, | |
99 Version: fmt.Sprintf("%d", p.Version), | |
100 }) | |
101 } | |
102 | |
103 dims := make([]*swarming_api.SwarmingRpcsStringPair, 0, len(c.TaskSpec.D
imensions)) | |
104 dimsMap := make(map[string]string, len(c.TaskSpec.Dimensions)) | |
105 for _, d := range c.TaskSpec.Dimensions { | |
106 split := strings.SplitN(d, ":", 2) | |
107 key := split[0] | |
108 val := split[1] | |
109 dims = append(dims, &swarming_api.SwarmingRpcsStringPair{ | |
110 Key: key, | |
111 Value: val, | |
112 }) | |
113 dimsMap[key] = val | |
114 } | |
115 | |
116 return &swarming_api.SwarmingRpcsNewTaskRequest{ | |
117 ExpirationSecs: int64(swarming.RECOMMENDED_EXPIRATION.Seconds())
, | |
118 Name: c.Name, | |
119 Priority: int64(100.0 * c.TaskSpec.Priority), | |
120 Properties: &swarming_api.SwarmingRpcsTaskProperties{ | |
121 CipdInput: &swarming_api.SwarmingRpcsCipdInput{ | |
122 Packages: cipdPackages, | |
123 }, | |
124 Dimensions: dims, | |
125 ExecutionTimeoutSecs: int64(swarming.RECOMMENDED_HARD_TI
MEOUT.Seconds()), | |
126 InputsRef: &swarming_api.SwarmingRpcsFilesRef{ | |
127 Isolated: c.IsolatedInput, | |
128 Isolatedserver: isolate.ISOLATE_SERVER_URL, | |
129 Namespace: isolate.DEFAULT_NAMESPACE, | |
130 }, | |
131 IoTimeoutSecs: int64(swarming.RECOMMENDED_IO_TIMEOUT.Sec
onds()), | |
132 }, | |
133 Tags: db.TagsForTask(c.Name, id, c.TaskSpec.Priority, c.Repo, c.
Revision, dimsMap), | |
134 User: "skia-build-scheduler", | |
135 } | |
136 } | |
137 | |
138 // allDepsMet determines whether all dependencies for the given task candidate | |
139 // have been satisfied, and if so, returns their isolated outputs. | |
140 func (c *taskCandidate) allDepsMet(cache db.TaskCache) (bool, []string, error) { | |
141 isolatedHashes := make([]string, 0, len(c.TaskSpec.Dependencies)) | |
142 for _, depName := range c.TaskSpec.Dependencies { | |
143 d, err := cache.GetTaskForCommit(c.Repo, c.Revision, depName) | |
144 if err != nil { | |
145 return false, nil, err | |
146 } | |
147 if d == nil { | |
148 return false, nil, nil | |
149 } | |
150 if !d.Done() || !d.Success() || d.IsolatedOutput == "" { | |
151 return false, nil, nil | |
152 } | |
153 isolatedHashes = append(isolatedHashes, d.IsolatedOutput) | |
154 } | |
155 return true, isolatedHashes, nil | |
156 } | |
157 | |
158 // taskCandidateSlice is an alias used for sorting a slice of taskCandidates. | |
159 type taskCandidateSlice []*taskCandidate | |
160 | |
161 func (s taskCandidateSlice) Len() int { return len(s) } | |
162 func (s taskCandidateSlice) Swap(i, j int) { | |
163 s[i], s[j] = s[j], s[i] | |
164 } | |
165 func (s taskCandidateSlice) Less(i, j int) bool { | |
166 return s[i].Score > s[j].Score // candidates sort in decreasing order. | |
167 } | |
OLD | NEW |