Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(175)

Side by Side Diff: milo/appengine/buildbot/pubsub.go

Issue 2450343003: Milo: Pubsub pending build fixes. (Closed)
Patch Set: fix Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The LUCI Authors. All rights reserved. 1 // Copyright 2016 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0 2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file. 3 // that can be found in the LICENSE file.
4 4
5 package buildbot 5 package buildbot
6 6
7 import ( 7 import (
8 "bytes" 8 "bytes"
9 "compress/gzip" 9 "compress/gzip"
10 "compress/zlib" 10 "compress/zlib"
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 // Internal 68 // Internal
69 Internal bool 69 Internal bool
70 // Data is the json serialzed and gzipped blob of the master data. 70 // Data is the json serialzed and gzipped blob of the master data.
71 Data []byte `gae:",noindex"` 71 Data []byte `gae:",noindex"`
72 // Modified is when this entry was last modified. 72 // Modified is when this entry was last modified.
73 Modified time.Time 73 Modified time.Time
74 } 74 }
75 75
76 func putDSMasterJSON( 76 func putDSMasterJSON(
77 c context.Context, master *buildbotMaster, internal bool) error { 77 c context.Context, master *buildbotMaster, internal bool) error {
78 // Trim pending build states. These things are large and we can't reall y
79 // store more than 25 of them. If this becomes an issue again, we'll ha ve
80 // to trim out things from the pending build state such as the changed
81 // file list, commit comments, etc.
82 for _, builder := range master.Builders { 78 for _, builder := range master.Builders {
83 » » if len(builder.PendingBuildStates) > 25 { 79 » » // Trim out extra info in the "Changes" portion of the pending b uild state,
84 » » » builder.PendingBuildStates = builder.PendingBuildStates[ 0:25] 80 » » // we don't actually need comments, files, and properties
81 » » for _, pbs := range builder.PendingBuildStates {
82 » » » for i := range pbs.Source.Changes {
83 » » » » pbs.Source.Changes[i].Comments = ""
84 » » » » pbs.Source.Changes[i].Files = nil
85 » » » » pbs.Source.Changes[i].Properties = nil
86 » » » }
85 } 87 }
86 } 88 }
87 entry := buildbotMasterEntry{ 89 entry := buildbotMasterEntry{
88 Name: master.Name, 90 Name: master.Name,
89 Internal: internal, 91 Internal: internal,
90 Modified: clock.Now(c).UTC(), 92 Modified: clock.Now(c).UTC(),
91 } 93 }
92 gzbs := bytes.Buffer{} 94 gzbs := bytes.Buffer{}
93 gsw := gzip.NewWriter(&gzbs) 95 gsw := gzip.NewWriter(&gzbs)
94 cw := iotools.CountingWriter{Writer: gsw} 96 cw := iotools.CountingWriter{Writer: gsw}
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 builder, ok := master.Builders[b.Buildername] 232 builder, ok := master.Builders[b.Buildername]
231 if !ok { 233 if !ok {
232 // Mark this build due to builder being removed. 234 // Mark this build due to builder being removed.
233 logging.Infof(c, "Expiring %s/%s/%d due to builder being removed", 235 logging.Infof(c, "Expiring %s/%s/%d due to builder being removed",
234 master.Name, b.Buildername, b.Number) 236 master.Name, b.Buildername, b.Number)
235 err = expireBuild(c, b) 237 err = expireBuild(c, b)
236 if err != nil { 238 if err != nil {
237 logging.WithError(err).Errorf(c, "Could not expi re build") 239 logging.WithError(err).Errorf(c, "Could not expi re build")
238 return 500 240 return 500
239 } 241 }
242 continue
240 } 243 }
241 244
242 found := false 245 found := false
243 for _, bnum := range builder.CurrentBuilds { 246 for _, bnum := range builder.CurrentBuilds {
244 if b.Number == bnum { 247 if b.Number == bnum {
245 found = true 248 found = true
246 break 249 break
247 } 250 }
248 } 251 }
249 if !found { 252 if !found {
250 // Mark this build due to build not current anymore. 253 // Mark this build due to build not current anymore.
251 logging.Infof(c, "Expiring %s/%s/%d due to build not cur rent", 254 logging.Infof(c, "Expiring %s/%s/%d due to build not cur rent",
252 master.Name, b.Buildername, b.Number) 255 master.Name, b.Buildername, b.Number)
253 err = expireBuild(c, b) 256 err = expireBuild(c, b)
254 if err != nil { 257 if err != nil {
255 logging.WithError(err).Errorf(c, "Could not expi re build") 258 logging.WithError(err).Errorf(c, "Could not expi re build")
256 return 500 259 return 500
257 } 260 }
258 } 261 }
259 } 262 }
260 return 0 263 return 0
261 } 264 }
262 265
263 // PubSubHandler is a webhook that stores the builds coming in from pubsub. 266 // PubSubHandler is a webhook that stores the builds coming in from pubsub.
264 func PubSubHandler(ctx *router.Context) { 267 func PubSubHandler(ctx *router.Context) {
265 c, h, r := ctx.Context, ctx.Writer, ctx.Request 268 c, h, r := ctx.Context, ctx.Writer, ctx.Request
266 269
267 msg := pubSubSubscription{} 270 msg := pubSubSubscription{}
268 defer r.Body.Close() 271 defer r.Body.Close()
272 logging.Infof(c, "Message is %d bytes long", r.ContentLength)
269 dec := json.NewDecoder(r.Body) 273 dec := json.NewDecoder(r.Body)
270 if err := dec.Decode(&msg); err != nil { 274 if err := dec.Decode(&msg); err != nil {
271 logging.WithError(err).Errorf( 275 logging.WithError(err).Errorf(
272 c, "Could not decode message. %s", err) 276 c, "Could not decode message. %s", err)
273 h.WriteHeader(200) // This is a hard failure, we don't want PubS ub to retry. 277 h.WriteHeader(200) // This is a hard failure, we don't want PubS ub to retry.
274 return 278 return
275 } 279 }
276 internal := true 280 internal := true
277 switch msg.Subscription { 281 switch msg.Subscription {
278 case publicSubName: 282 case publicSubName:
(...skipping 22 matching lines...) Expand all
301 logging.Infof(c, "There are %d builds", len(builds)) 305 logging.Infof(c, "There are %d builds", len(builds))
302 if master != nil { 306 if master != nil {
303 logging.Infof(c, "The master name is %s", master.Name) 307 logging.Infof(c, "The master name is %s", master.Name)
304 } else { 308 } else {
305 logging.Infof(c, "No master in this message") 309 logging.Infof(c, "No master in this message")
306 } 310 }
307 // This is used to cache the master used for extracting OS information. 311 // This is used to cache the master used for extracting OS information.
308 cachedMaster := buildbotMaster{} 312 cachedMaster := buildbotMaster{}
309 // Do not use PutMulti because we might hit the 1MB limit. 313 // Do not use PutMulti because we might hit the 1MB limit.
310 for _, build := range builds { 314 for _, build := range builds {
311 logging.Debugf(
312 c, "Checking for build %s/%s/%d", build.Master, build.Bu ildername, build.Number)
313 if build.Master == "" { 315 if build.Master == "" {
314 logging.Errorf(c, "Invalid message, missing master name" ) 316 logging.Errorf(c, "Invalid message, missing master name" )
315 h.WriteHeader(200) 317 h.WriteHeader(200)
316 return 318 return
317 } 319 }
318 existingBuild := &buildbotBuild{ 320 existingBuild := &buildbotBuild{
319 Master: build.Master, 321 Master: build.Master,
320 Buildername: build.Buildername, 322 Buildername: build.Buildername,
321 Number: build.Number, 323 Number: build.Number,
322 } 324 }
323 buildExists := false 325 buildExists := false
324 if err := ds.Get(c, existingBuild); err == nil { 326 if err := ds.Get(c, existingBuild); err == nil {
325 if existingBuild.Finished { 327 if existingBuild.Finished {
326 // Never replace a completed build. 328 // Never replace a completed build.
327 buildCounter.Add( 329 buildCounter.Add(
328 c, 1, false, build.Master, build.Builder name, false, "Rejected") 330 c, 1, false, build.Master, build.Builder name, false, "Rejected")
329 logging.Debugf(
330 c, "Found build %s/%s/%d and it's finish ed, skipping", build.Master, build.Buildername, build.Number)
331 continue 331 continue
332 } 332 }
333 buildExists = true 333 buildExists = true
334 } 334 }
335 // Also set the finished and internal bit. 335 // Also set the finished and internal bit.
336 build.Finished = false 336 build.Finished = false
337 if len(build.Times) == 2 && build.Times[1] != nil { 337 if len(build.Times) == 2 && build.Times[1] != nil {
338 build.Finished = true 338 build.Finished = true
339 } 339 }
340 build.Internal = internal 340 build.Internal = internal
341 // Try to get the OS information on a best-effort basis. This a ssumes that all 341 // Try to get the OS information on a best-effort basis. This a ssumes that all
342 // builds come from one master. 342 // builds come from one master.
343 build.OSFamily, build.OSVersion = getOSInfo(c, build, &cachedMas ter) 343 build.OSFamily, build.OSVersion = getOSInfo(c, build, &cachedMas ter)
344 err = ds.Put(c, build) 344 err = ds.Put(c, build)
345 if err != nil { 345 if err != nil {
346 if _, ok := err.(errTooBig); ok { 346 if _, ok := err.(errTooBig); ok {
347 // This will never work, we don't want PubSub to retry. 347 // This will never work, we don't want PubSub to retry.
348 logging.WithError(err).Errorf( 348 logging.WithError(err).Errorf(
349 c, "Could not save build to datastore, f ailing permanently") 349 c, "Could not save build to datastore, f ailing permanently")
350 h.WriteHeader(200) 350 h.WriteHeader(200)
351 } else { 351 } else {
352 // This is transient, we do want PubSub to retry . 352 // This is transient, we do want PubSub to retry .
353 logging.WithError(err).Errorf(c, "Could not save build in datastore") 353 logging.WithError(err).Errorf(c, "Could not save build in datastore")
354 h.WriteHeader(500) 354 h.WriteHeader(500)
355 } 355 }
356 return 356 return
357 } 357 }
358 logging.Debugf(
359 c, "Saved build %s/%s/%d, it is %s",
360 build.Master, build.Buildername, build.Number, build.Fin ished)
361 if buildExists { 358 if buildExists {
362 buildCounter.Add( 359 buildCounter.Add(
363 c, 1, false, build.Master, build.Buildername, bu ild.Finished, "Replaced") 360 c, 1, false, build.Master, build.Buildername, bu ild.Finished, "Replaced")
364 } else { 361 } else {
365 buildCounter.Add( 362 buildCounter.Add(
366 c, 1, false, build.Master, build.Buildername, bu ild.Finished, "New") 363 c, 1, false, build.Master, build.Buildername, bu ild.Finished, "New")
367 } 364 }
368 365
369 } 366 }
370 if master != nil { 367 if master != nil {
371 code := doMaster(c, master, internal) 368 code := doMaster(c, master, internal)
372 if code != 0 { 369 if code != 0 {
373 h.WriteHeader(code) 370 h.WriteHeader(code)
374 return 371 return
375 } 372 }
376 } 373 }
377 h.WriteHeader(200) 374 h.WriteHeader(200)
378 } 375 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698