| 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 |