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

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

Issue 2043423004: Make HTTP middleware easier to use (Closed) Base URL: https://github.com/luci/luci-go@master
Patch Set: Update tests Created 4 years, 6 months 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
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 "encoding/base64" 10 "encoding/base64"
11 "encoding/json" 11 "encoding/json"
12 "net/http"
13 "time" 12 "time"
14 13
15 "github.com/luci/gae/service/datastore" 14 "github.com/luci/gae/service/datastore"
16 "github.com/luci/luci-go/common/clock" 15 "github.com/luci/luci-go/common/clock"
17 "github.com/luci/luci-go/common/iotools" 16 "github.com/luci/luci-go/common/iotools"
18 log "github.com/luci/luci-go/common/logging" 17 log "github.com/luci/luci-go/common/logging"
18 "github.com/luci/luci-go/server/router"
19 19
20 "github.com/julienschmidt/httprouter"
21 "golang.org/x/net/context" 20 "golang.org/x/net/context"
22 ) 21 )
23 22
24 var ( 23 var (
25 // subName is the name of the pubsub subscription that milo is expecting . 24 // subName is the name of the pubsub subscription that milo is expecting .
26 // TODO(hinoka): This should be read from luci-config. 25 // TODO(hinoka): This should be read from luci-config.
27 subName = "projects/luci-milo/subscriptions/buildbot-public" 26 subName = "projects/luci-milo/subscriptions/buildbot-public"
28 ) 27 )
29 28
30 type pubSubMessage struct { 29 type pubSubMessage struct {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 bm.Builds = append(bm.Builds, build) 131 bm.Builds = append(bm.Builds, build)
133 slave.RunningbuildsMap[build.Buildername] = append( 132 slave.RunningbuildsMap[build.Buildername] = append(
134 slave.RunningbuildsMap[build.Buildername], build .Number) 133 slave.RunningbuildsMap[build.Buildername], build .Number)
135 } 134 }
136 slave.Runningbuilds = nil 135 slave.Runningbuilds = nil
137 } 136 }
138 return bm.Builds, bm.Master, nil 137 return bm.Builds, bm.Master, nil
139 } 138 }
140 139
141 // PubSubHandler is a webhook that stores the builds coming in from pubsub. 140 // PubSubHandler is a webhook that stores the builds coming in from pubsub.
142 func PubSubHandler( 141 func PubSubHandler(ctx *router.Context) {
143 » c context.Context, h http.ResponseWriter, r *http.Request, p httprouter. Params) { 142 » c, h, r := ctx.Context, ctx.Writer, ctx.Request
143 » defer r.Body.Close()
144 msg := pubSubSubscription{} 144 msg := pubSubSubscription{}
145 defer r.Body.Close()
146 dec := json.NewDecoder(r.Body) 145 dec := json.NewDecoder(r.Body)
147 if err := dec.Decode(&msg); err != nil { 146 if err := dec.Decode(&msg); err != nil {
148 log.WithError(err).Errorf( 147 log.WithError(err).Errorf(
149 c, "Could not decode message. %s", err) 148 c, "Could not decode message. %s", err)
150 h.WriteHeader(200) // This is a hard failure, we don't want PubS ub to retry. 149 h.WriteHeader(200) // This is a hard failure, we don't want PubS ub to retry.
150 ctx.Abort()
151 return 151 return
152 } 152 }
153 if msg.Subscription != subName { 153 if msg.Subscription != subName {
154 log.Errorf( 154 log.Errorf(
155 c, "Subscription name %s does not match %s", msg.Subscri ption, subName) 155 c, "Subscription name %s does not match %s", msg.Subscri ption, subName)
156 h.WriteHeader(200) 156 h.WriteHeader(200)
157 ctx.Abort()
157 return 158 return
158 } 159 }
159 bbMsg, err := msg.GetData() 160 bbMsg, err := msg.GetData()
160 if err != nil { 161 if err != nil {
161 log.WithError(err).Errorf(c, "Could not decode message %s", err) 162 log.WithError(err).Errorf(c, "Could not decode message %s", err)
162 h.WriteHeader(200) 163 h.WriteHeader(200)
164 ctx.Abort()
163 return 165 return
164 } 166 }
165 builds, master, err := unmarshal(c, bbMsg) 167 builds, master, err := unmarshal(c, bbMsg)
166 if err != nil { 168 if err != nil {
167 log.WithError(err).Errorf(c, "Could not unmarshal message %s", e rr) 169 log.WithError(err).Errorf(c, "Could not unmarshal message %s", e rr)
168 h.WriteHeader(200) 170 h.WriteHeader(200)
171 ctx.Abort()
169 return 172 return
170 } 173 }
171 log.Infof(c, "There are %d builds and master %s", len(builds), master.Na me) 174 log.Infof(c, "There are %d builds and master %s", len(builds), master.Na me)
172 ds := datastore.Get(c) 175 ds := datastore.Get(c)
173 // Do not use PutMulti because we might hit the 1MB limit. 176 // Do not use PutMulti because we might hit the 1MB limit.
174 for _, build := range builds { 177 for _, build := range builds {
175 log.Debugf( 178 log.Debugf(
176 c, "Checking for build %s/%s/%d", build.Master, build.Bu ildername, build.Number) 179 c, "Checking for build %s/%s/%d", build.Master, build.Bu ildername, build.Number)
177 if build.Master == "" { 180 if build.Master == "" {
178 log.Errorf(c, "Invalid message, missing master name") 181 log.Errorf(c, "Invalid message, missing master name")
179 h.WriteHeader(200) 182 h.WriteHeader(200)
183 ctx.Abort()
180 return 184 return
181 } 185 }
182 existingBuild := &buildbotBuild{ 186 existingBuild := &buildbotBuild{
183 Master: build.Master, 187 Master: build.Master,
184 Buildername: build.Buildername, 188 Buildername: build.Buildername,
185 Number: build.Number, 189 Number: build.Number,
186 } 190 }
187 if err := ds.Get(existingBuild); err == nil { 191 if err := ds.Get(existingBuild); err == nil {
188 if existingBuild.Times[1] != nil && build.Times[1] == ni l { 192 if existingBuild.Times[1] != nil && build.Times[1] == ni l {
189 // Never replace a completed build with a pendin g build. 193 // Never replace a completed build with a pendin g build.
190 continue 194 continue
191 } 195 }
192 } 196 }
193 err = ds.Put(&build) 197 err = ds.Put(&build)
194 if err != nil { 198 if err != nil {
195 log.WithError(err).Errorf(c, "Could not save build in da tastore %s", err) 199 log.WithError(err).Errorf(c, "Could not save build in da tastore %s", err)
196 // This is transient, we do want PubSub to retry. 200 // This is transient, we do want PubSub to retry.
197 h.WriteHeader(500) 201 h.WriteHeader(500)
202 ctx.Abort()
198 return 203 return
199 } 204 }
200 } 205 }
201 if master != nil { 206 if master != nil {
202 // TODO(hinoka): Internal builds. 207 // TODO(hinoka): Internal builds.
203 err = putDSMasterJSON(c, master, false) 208 err = putDSMasterJSON(c, master, false)
204 if err != nil { 209 if err != nil {
205 log.WithError(err).Errorf( 210 log.WithError(err).Errorf(
206 c, "Could not save master in datastore %s", err) 211 c, "Could not save master in datastore %s", err)
207 // This is transient, we do want PubSub to retry. 212 // This is transient, we do want PubSub to retry.
208 h.WriteHeader(500) 213 h.WriteHeader(500)
214 ctx.Abort()
209 return 215 return
210 } 216 }
211 } 217 }
212 h.WriteHeader(200) 218 h.WriteHeader(200)
iannucci 2016/06/13 19:23:28 missed one?
213 } 219 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698