OLD | NEW |
1 // Copyright 2016 The LUCI Authors. | 1 // Copyright 2016 The LUCI Authors. |
2 // | 2 // |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
6 // | 6 // |
7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
8 // | 8 // |
9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 target.FinishedBuilds = append(target.FinishedBu
ilds, mb) | 224 target.FinishedBuilds = append(target.FinishedBu
ilds, mb) |
225 } | 225 } |
226 | 226 |
227 default: | 227 default: |
228 panic("impossible") | 228 panic("impossible") |
229 } | 229 } |
230 } | 230 } |
231 return nil | 231 return nil |
232 } | 232 } |
233 | 233 |
234 type builderQuery struct { | 234 // parseTimestamp converts buildbucket timestamp in microseconds to time.Time |
235 » Bucket string | 235 func parseTimestamp(microseconds int64) time.Time { |
236 » Builder string | 236 » if microseconds == 0 { |
237 » Limit int | 237 » » return time.Time{} |
| 238 » } |
| 239 » return time.Unix(microseconds/1e6, microseconds%1e6*1000).UTC() |
238 } | 240 } |
239 | 241 |
240 // builderImpl is the implementation for getting a milo builder page from buildb
ucket. | 242 type newBuildsFirst []*resp.BuildSummary |
241 // if maxCompletedBuilds < 0, 25 is used. | 243 |
242 func builderImpl(c context.Context, q builderQuery) (*resp.Builder, error) { | 244 func (a newBuildsFirst) Len() int { return len(a) } |
| 245 func (a newBuildsFirst) Swap(i, j int) { a[i], a[j] = a[j], a[i] } |
| 246 func (a newBuildsFirst) Less(i, j int) bool { |
| 247 » return a[i].PendingTime.Started.After(a[j].PendingTime.Started) |
| 248 } |
| 249 |
| 250 // GetBuilder is used by buildsource.BuilderID.Get to obtain the resp.Builder. |
| 251 func GetBuilder(c context.Context, bucket, builder string, limit int) (*resp.Bui
lder, error) { |
243 settings := common.GetSettings(c) | 252 settings := common.GetSettings(c) |
244 if settings.Buildbucket == nil || settings.Buildbucket.Host == "" { | 253 if settings.Buildbucket == nil || settings.Buildbucket.Host == "" { |
245 logging.Errorf(c, "missing buildbucket settings") | 254 logging.Errorf(c, "missing buildbucket settings") |
246 return nil, errors.New("missing buildbucket settings") | 255 return nil, errors.New("missing buildbucket settings") |
247 } | 256 } |
248 host := settings.Buildbucket.Host | 257 host := settings.Buildbucket.Host |
249 | 258 |
250 » if q.Limit < 0 { | 259 » if limit < 0 { |
251 » » q.Limit = 20 | 260 » » limit = 20 |
252 } | 261 } |
253 | 262 |
254 result := &resp.Builder{ | 263 result := &resp.Builder{ |
255 » » Name: q.Builder, | 264 » » Name: builder, |
256 } | 265 } |
257 if host == "debug" { | 266 if host == "debug" { |
258 » » return result, getDebugBuilds(c, q.Bucket, q.Builder, q.Limit, r
esult) | 267 » » return result, getDebugBuilds(c, bucket, builder, limit, result) |
259 } | 268 } |
260 client, err := newBuildbucketClient(c, host) | 269 client, err := newBuildbucketClient(c, host) |
261 if err != nil { | 270 if err != nil { |
262 return nil, err | 271 return nil, err |
263 } | 272 } |
264 | 273 |
265 fetch := func(target *[]*resp.BuildSummary, status string, count int) er
ror { | 274 fetch := func(target *[]*resp.BuildSummary, status string, count int) er
ror { |
266 » » builds, err := fetchBuilds(c, client, q.Bucket, q.Builder, statu
s, count) | 275 » » builds, err := fetchBuilds(c, client, bucket, builder, status, c
ount) |
267 if err != nil { | 276 if err != nil { |
268 logging.Errorf(c, "Could not fetch builds with status %s
: %s", status, err) | 277 logging.Errorf(c, "Could not fetch builds with status %s
: %s", status, err) |
269 return err | 278 return err |
270 } | 279 } |
271 *target = make([]*resp.BuildSummary, len(builds)) | 280 *target = make([]*resp.BuildSummary, len(builds)) |
272 for i, bb := range builds { | 281 for i, bb := range builds { |
273 (*target)[i] = toMiloBuild(c, bb) | 282 (*target)[i] = toMiloBuild(c, bb) |
274 } | 283 } |
275 return nil | 284 return nil |
276 } | 285 } |
277 // fetch pending, current and finished builds concurrently. | 286 // fetch pending, current and finished builds concurrently. |
278 // Why not a single request? Because we need different build number | 287 // Why not a single request? Because we need different build number |
279 // limits for different statuses. | 288 // limits for different statuses. |
280 return result, parallel.FanOutIn(func(work chan<- func() error) { | 289 return result, parallel.FanOutIn(func(work chan<- func() error) { |
281 work <- func() error { | 290 work <- func() error { |
282 return fetch(&result.PendingBuilds, StatusScheduled, -1) | 291 return fetch(&result.PendingBuilds, StatusScheduled, -1) |
283 } | 292 } |
284 work <- func() error { | 293 work <- func() error { |
285 return fetch(&result.CurrentBuilds, StatusStarted, -1) | 294 return fetch(&result.CurrentBuilds, StatusStarted, -1) |
286 } | 295 } |
287 work <- func() error { | 296 work <- func() error { |
288 » » » return fetch(&result.FinishedBuilds, StatusCompleted, q.
Limit) | 297 » » » return fetch(&result.FinishedBuilds, StatusCompleted, li
mit) |
289 } | 298 } |
290 }) | 299 }) |
291 } | 300 } |
292 | |
293 // parseTimestamp converts buildbucket timestamp in microseconds to time.Time | |
294 func parseTimestamp(microseconds int64) time.Time { | |
295 if microseconds == 0 { | |
296 return time.Time{} | |
297 } | |
298 return time.Unix(microseconds/1e6, microseconds%1e6*1000).UTC() | |
299 } | |
300 | |
301 type newBuildsFirst []*resp.BuildSummary | |
302 | |
303 func (a newBuildsFirst) Len() int { return len(a) } | |
304 func (a newBuildsFirst) Swap(i, j int) { a[i], a[j] = a[j], a[i] } | |
305 func (a newBuildsFirst) Less(i, j int) bool { | |
306 return a[i].PendingTime.Started.After(a[j].PendingTime.Started) | |
307 } | |
OLD | NEW |