blob: 357a2dd87571d4b5d61e3702e57a28abee2b84c7 [file] [log] [blame]
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"encoding/json"
"fmt"
"net/http"
"context"
"google.golang.org/appengine"
"google.golang.org/appengine/datastore"
)
func updateBenchmark(w http.ResponseWriter, r *http.Request) {
if !appengine.IsDevAppServer() {
fmt.Fprint(w, "Update must not run on real server.")
return
}
if r.Method != "POST" {
fmt.Fprintf(w, "bad request method")
return
}
c := contextForRequest(r)
if !validKey(c, r.FormValue("key"), r.FormValue("builder")) {
fmt.Fprintf(w, "bad builder/key")
return
}
defer r.Body.Close()
var hashes []string
if err := json.NewDecoder(r.Body).Decode(&hashes); err != nil {
fmt.Fprintf(w, "failed to decode request: %v", err)
return
}
ncommit := 0
nrun := 0
tx := func(c context.Context) error {
var cr *CommitRun
for _, hash := range hashes {
// Update Commit.
com := &Commit{Hash: hash}
err := datastore.Get(c, com.Key(c), com)
if err != nil && err != datastore.ErrNoSuchEntity {
return fmt.Errorf("fetching Commit: %v", err)
}
if err == datastore.ErrNoSuchEntity {
continue
}
com.NeedsBenchmarking = true
com.PerfResults = nil
if err := putCommit(c, com); err != nil {
return err
}
ncommit++
// create PerfResult
res := &PerfResult{CommitHash: com.Hash, CommitNum: com.Num}
err = datastore.Get(c, res.Key(c), res)
if err != nil && err != datastore.ErrNoSuchEntity {
return fmt.Errorf("fetching PerfResult: %v", err)
}
if err == datastore.ErrNoSuchEntity {
if _, err := datastore.Put(c, res.Key(c), res); err != nil {
return fmt.Errorf("putting PerfResult: %v", err)
}
}
// Update CommitRun.
if cr != nil && cr.StartCommitNum != com.Num/PerfRunLength*PerfRunLength {
if _, err := datastore.Put(c, cr.Key(c), cr); err != nil {
return fmt.Errorf("putting CommitRun: %v", err)
}
nrun++
cr = nil
}
if cr == nil {
var err error
cr, err = GetCommitRun(c, com.Num)
if err != nil {
return fmt.Errorf("getting CommitRun: %v", err)
}
}
if com.Num < cr.StartCommitNum || com.Num >= cr.StartCommitNum+PerfRunLength {
return fmt.Errorf("commit num %v out of range [%v, %v)", com.Num, cr.StartCommitNum, cr.StartCommitNum+PerfRunLength)
}
idx := com.Num - cr.StartCommitNum
cr.Hash[idx] = com.Hash
cr.User[idx] = shortDesc(com.User)
cr.Desc[idx] = shortDesc(com.Desc)
cr.Time[idx] = com.Time
cr.NeedsBenchmarking[idx] = com.NeedsBenchmarking
}
if cr != nil {
if _, err := datastore.Put(c, cr.Key(c), cr); err != nil {
return fmt.Errorf("putting CommitRun: %v", err)
}
nrun++
}
return nil
}
if err := datastore.RunInTransaction(c, tx, nil); err != nil {
fmt.Fprintf(w, "failed to execute tx: %v", err)
return
}
fmt.Fprintf(w, "OK (updated %v commits and %v commit runs)", ncommit, nrun)
}