| OLD | NEW |
| 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 "encoding/json" | 10 "encoding/json" |
| 11 | 11 |
| 12 "google.golang.org/grpc" | 12 "google.golang.org/grpc" |
| 13 "google.golang.org/grpc/codes" | 13 "google.golang.org/grpc/codes" |
| 14 | 14 |
| 15 "github.com/golang/protobuf/ptypes/timestamp" | 15 "github.com/golang/protobuf/ptypes/timestamp" |
| 16 ds "github.com/luci/gae/service/datastore" | 16 ds "github.com/luci/gae/service/datastore" |
| 17 "github.com/luci/luci-go/common/iotools" | 17 "github.com/luci/luci-go/common/iotools" |
| 18 "github.com/luci/luci-go/common/logging" | 18 "github.com/luci/luci-go/common/logging" |
| 19 milo "github.com/luci/luci-go/milo/api/proto" | 19 milo "github.com/luci/luci-go/milo/api/proto" |
| 20 "golang.org/x/net/context" | 20 "golang.org/x/net/context" |
| 21 ) | 21 ) |
| 22 | 22 |
| 23 // Service is a service implementation that displays BuildBot builds. | 23 // Service is a service implementation that displays BuildBot builds. |
| 24 type Service struct{} | 24 type Service struct{} |
| 25 | 25 |
| 26 var errNotFoundGRPC = grpc.Errorf(codes.NotFound, "Master Not Found") | 26 var errNotFoundGRPC = grpc.Errorf(codes.NotFound, "Master Not Found") |
| 27 | 27 |
| 28 // GetBuildbotBuildJSON implements milo.BuildbotServer. |
| 28 func (s *Service) GetBuildbotBuildJSON( | 29 func (s *Service) GetBuildbotBuildJSON( |
| 29 c context.Context, req *milo.BuildbotBuildRequest) ( | 30 c context.Context, req *milo.BuildbotBuildRequest) ( |
| 30 *milo.BuildbotBuildJSON, error) { | 31 *milo.BuildbotBuildJSON, error) { |
| 31 | 32 |
| 32 if req.Master == "" { | 33 if req.Master == "" { |
| 33 return nil, grpc.Errorf(codes.InvalidArgument, "No master specif
ied") | 34 return nil, grpc.Errorf(codes.InvalidArgument, "No master specif
ied") |
| 34 } | 35 } |
| 35 if req.Builder == "" { | 36 if req.Builder == "" { |
| 36 return nil, grpc.Errorf(codes.InvalidArgument, "No builder speci
fied") | 37 return nil, grpc.Errorf(codes.InvalidArgument, "No builder speci
fied") |
| 37 } | 38 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 48 | 49 |
| 49 bs, err := json.Marshal(b) | 50 bs, err := json.Marshal(b) |
| 50 if err != nil { | 51 if err != nil { |
| 51 return nil, err | 52 return nil, err |
| 52 } | 53 } |
| 53 | 54 |
| 54 // Marshal the build back into JSON format. | 55 // Marshal the build back into JSON format. |
| 55 return &milo.BuildbotBuildJSON{Data: bs}, nil | 56 return &milo.BuildbotBuildJSON{Data: bs}, nil |
| 56 } | 57 } |
| 57 | 58 |
| 59 // GetBuildbotBuildsJSON implements milo.BuildbotServer. |
| 58 func (s *Service) GetBuildbotBuildsJSON( | 60 func (s *Service) GetBuildbotBuildsJSON( |
| 59 c context.Context, req *milo.BuildbotBuildsRequest) ( | 61 c context.Context, req *milo.BuildbotBuildsRequest) ( |
| 60 *milo.BuildbotBuildsJSON, error) { | 62 *milo.BuildbotBuildsJSON, error) { |
| 61 | 63 |
| 62 if req.Master == "" { | 64 if req.Master == "" { |
| 63 return nil, grpc.Errorf(codes.InvalidArgument, "No master specif
ied") | 65 return nil, grpc.Errorf(codes.InvalidArgument, "No master specif
ied") |
| 64 } | 66 } |
| 65 if req.Builder == "" { | 67 if req.Builder == "" { |
| 66 return nil, grpc.Errorf(codes.InvalidArgument, "No builder speci
fied") | 68 return nil, grpc.Errorf(codes.InvalidArgument, "No builder speci
fied") |
| 67 } | 69 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 84 | 86 |
| 85 q := ds.NewQuery("buildbotBuild") | 87 q := ds.NewQuery("buildbotBuild") |
| 86 q = q.Eq("master", req.Master). | 88 q = q.Eq("master", req.Master). |
| 87 Eq("builder", req.Builder). | 89 Eq("builder", req.Builder). |
| 88 Limit(limit). | 90 Limit(limit). |
| 89 Order("-number") | 91 Order("-number") |
| 90 if req.IncludeCurrent == false { | 92 if req.IncludeCurrent == false { |
| 91 q = q.Eq("finished", true) | 93 q = q.Eq("finished", true) |
| 92 } | 94 } |
| 93 builds := []*buildbotBuild{} | 95 builds := []*buildbotBuild{} |
| 94 » err = ds.GetAll(c, q, &builds) | 96 » err = getBuildQueryBatcher(c).GetAll(c, q, &builds) |
| 95 if err != nil { | 97 if err != nil { |
| 96 return nil, err | 98 return nil, err |
| 97 } | 99 } |
| 98 | 100 |
| 99 results := make([]*milo.BuildbotBuildJSON, len(builds)) | 101 results := make([]*milo.BuildbotBuildJSON, len(builds)) |
| 100 for i, b := range builds { | 102 for i, b := range builds { |
| 101 // In theory we could do this in parallel, but it doesn't actual
ly go faster | 103 // In theory we could do this in parallel, but it doesn't actual
ly go faster |
| 102 // since AppEngine is single-cored. | 104 // since AppEngine is single-cored. |
| 103 bs, err := json.Marshal(b) | 105 bs, err := json.Marshal(b) |
| 104 if err != nil { | 106 if err != nil { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 for _, buildNum := range builds { | 146 for _, buildNum := range builds { |
| 145 slave.Runningbuilds = append(slave.Runningbuilds
, &buildbotBuild{ | 147 slave.Runningbuilds = append(slave.Runningbuilds
, &buildbotBuild{ |
| 146 Master: req.Name, | 148 Master: req.Name, |
| 147 Buildername: builderName, | 149 Buildername: builderName, |
| 148 Number: buildNum, | 150 Number: buildNum, |
| 149 }) | 151 }) |
| 150 } | 152 } |
| 151 } | 153 } |
| 152 if err := ds.Get(c, slave.Runningbuilds); err != nil { | 154 if err := ds.Get(c, slave.Runningbuilds); err != nil { |
| 153 logging.WithError(err).Errorf(c, | 155 logging.WithError(err).Errorf(c, |
| 154 » » » » "Encountered error while trying to fetch running
builds for %s: %s", | 156 » » » » "Encountered error while trying to fetch running
builds for %s: %v", |
| 155 master.Name, slave.Runningbuilds) | 157 master.Name, slave.Runningbuilds) |
| 156 return nil, err | 158 return nil, err |
| 157 } | 159 } |
| 158 } | 160 } |
| 159 | 161 |
| 160 // Also inject cached builds information. | 162 // Also inject cached builds information. |
| 161 for builderName, builder := range master.Builders { | 163 for builderName, builder := range master.Builders { |
| 162 // Get the most recent 50 buildNums on the builder to simulate w
hat the | 164 // Get the most recent 50 buildNums on the builder to simulate w
hat the |
| 163 // cachedBuilds field looks like from the real buildbot master j
son. | 165 // cachedBuilds field looks like from the real buildbot master j
son. |
| 164 q := ds.NewQuery("buildbotBuild"). | 166 q := ds.NewQuery("buildbotBuild"). |
| 165 Eq("finished", true). | 167 Eq("finished", true). |
| 166 Eq("master", req.Name). | 168 Eq("master", req.Name). |
| 167 Eq("builder", builderName). | 169 Eq("builder", builderName). |
| 168 Limit(50). | 170 Limit(50). |
| 169 Order("-number"). | 171 Order("-number"). |
| 170 KeysOnly(true) | 172 KeysOnly(true) |
| 171 var builds []*buildbotBuild | 173 var builds []*buildbotBuild |
| 172 » » err := ds.GetAll(c, q, &builds) | 174 » » err := getBuildQueryBatcher(c).GetAll(c, q, &builds) |
| 173 if err != nil { | 175 if err != nil { |
| 174 return nil, err | 176 return nil, err |
| 175 } | 177 } |
| 176 builder.CachedBuilds = make([]int, len(builds)) | 178 builder.CachedBuilds = make([]int, len(builds)) |
| 177 for i, b := range builds { | 179 for i, b := range builds { |
| 178 builder.CachedBuilds[i] = b.Number | 180 builder.CachedBuilds[i] = b.Number |
| 179 } | 181 } |
| 180 } | 182 } |
| 181 | 183 |
| 182 // And re-compress it. | 184 // And re-compress it. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 194 | 196 |
| 195 return &milo.CompressedMasterJSON{ | 197 return &milo.CompressedMasterJSON{ |
| 196 Internal: entry.Internal, | 198 Internal: entry.Internal, |
| 197 Modified: ×tamp.Timestamp{ | 199 Modified: ×tamp.Timestamp{ |
| 198 Seconds: entry.Modified.Unix(), | 200 Seconds: entry.Modified.Unix(), |
| 199 Nanos: int32(entry.Modified.Nanosecond()), | 201 Nanos: int32(entry.Modified.Nanosecond()), |
| 200 }, | 202 }, |
| 201 Data: gzbs.Bytes(), | 203 Data: gzbs.Bytes(), |
| 202 }, nil | 204 }, nil |
| 203 } | 205 } |
| OLD | NEW |