storage: add Context arguments for queries
Change-Id: I0ba5b534e0d5262e2626351d10564219d18f93a8
Reviewed-on: https://go-review.googlesource.com/41372
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/analysis/app/compare.go b/analysis/app/compare.go
index b1358e8..37d09d7 100644
--- a/analysis/app/compare.go
+++ b/analysis/app/compare.go
@@ -17,6 +17,7 @@
"strings"
"unicode"
+ "golang.org/x/net/context"
"golang.org/x/perf/benchstat"
"golang.org/x/perf/storage/benchfmt"
"golang.org/x/perf/storage/query"
@@ -134,6 +135,8 @@
// compare handles queries that require comparison of the groups in the query.
func (a *App) compare(w http.ResponseWriter, r *http.Request) {
+ ctx := requestContext(r)
+
if err := r.ParseForm(); err != nil {
http.Error(w, err.Error(), 500)
return
@@ -155,7 +158,7 @@
return
}
- data := a.compareQuery(q)
+ data := a.compareQuery(ctx, q)
w.Header().Set("Content-Type", "text/html; charset=utf-8")
if err := t.Execute(w, data); err != nil {
@@ -225,7 +228,7 @@
// fetchCompareResults fetches the matching results for a given query string.
// The results will be grouped into one or more groups based on either the query string or heuristics.
-func (a *App) fetchCompareResults(q string) ([]*resultGroup, error) {
+func (a *App) fetchCompareResults(ctx context.Context, q string) ([]*resultGroup, error) {
// Parse query
prefix, queries := parseQueryString(q)
@@ -239,7 +242,7 @@
if prefix != "" {
qPart = prefix + " " + qPart
}
- res := a.StorageClient.Query(qPart)
+ res := a.StorageClient.Query(ctx, qPart)
for res.Next() {
result := res.Result()
result.Content = elideKeyValues(result.Content, keys)
@@ -275,12 +278,12 @@
return groups, nil
}
-func (a *App) compareQuery(q string) *compareData {
+func (a *App) compareQuery(ctx context.Context, q string) *compareData {
if len(q) == 0 {
return &compareData{}
}
- groups, err := a.fetchCompareResults(q)
+ groups, err := a.fetchCompareResults(ctx, q)
if err != nil {
return &compareData{
Q: q,
@@ -349,6 +352,8 @@
// textCompare is called if benchsave is requesting a text-only analysis.
func (a *App) textCompare(w http.ResponseWriter, r *http.Request) {
+ ctx := requestContext(r)
+
if err := r.ParseForm(); err != nil {
http.Error(w, err.Error(), 500)
return
@@ -358,7 +363,7 @@
q := r.Form.Get("q")
- groups, err := a.fetchCompareResults(q)
+ groups, err := a.fetchCompareResults(ctx, q)
if err != nil {
// TODO(quentin): Should we serve this with a 500 or 404? This means the query was invalid or had no results.
fmt.Fprintf(w, "unable to analyze results: %v", err)
diff --git a/analysis/app/compare_test.go b/analysis/app/compare_test.go
index 5552c53..2fce9c0 100644
--- a/analysis/app/compare_test.go
+++ b/analysis/app/compare_test.go
@@ -12,6 +12,7 @@
"strings"
"testing"
+ "golang.org/x/net/context"
"golang.org/x/perf/storage"
"golang.org/x/perf/storage/benchfmt"
)
@@ -89,7 +90,7 @@
for _, q := range []string{"one vs two", "onetwo"} {
t.Run(q, func(t *testing.T) {
- data := a.compareQuery(q)
+ data := a.compareQuery(context.Background(), q)
if data.Error != "" {
t.Fatalf("compareQuery failed: %s", data.Error)
}
diff --git a/analysis/app/index.go b/analysis/app/index.go
index edd4ef4..d69aa90 100644
--- a/analysis/app/index.go
+++ b/analysis/app/index.go
@@ -30,7 +30,7 @@
}
var uploads []storage.UploadInfo
- ul := a.StorageClient.ListUploads("", []string{"by", "upload-time"}, 16)
+ ul := a.StorageClient.ListUploads(ctx, "", []string{"by", "upload-time"}, 16)
defer ul.Close()
for ul.Next() {
uploads = append(uploads, ul.Info())
diff --git a/analysis/app/trend.go b/analysis/app/trend.go
index af03dfe..6bf5a64 100644
--- a/analysis/app/trend.go
+++ b/analysis/app/trend.go
@@ -78,7 +78,7 @@
func (a *App) trendQuery(ctx context.Context, q string, opt plotOptions) *trendData {
d := &trendData{Q: q}
if q == "" {
- ul := a.StorageClient.ListUploads(`trend>`, []string{"by", "upload-time", "trend"}, 16)
+ ul := a.StorageClient.ListUploads(ctx, `trend>`, []string{"by", "upload-time", "trend"}, 16)
defer ul.Close()
for ul.Next() {
d.TrendUploads = append(d.TrendUploads, ul.Info())
@@ -90,7 +90,7 @@
}
// TODO(quentin): Chunk query based on matching upload IDs.
- res := a.StorageClient.Query(q)
+ res := a.StorageClient.Query(ctx, q)
defer res.Close()
t, resultCols := queryToTable(res)
if err := res.Err(); err != nil {
diff --git a/cmd/benchsave/benchsave.go b/cmd/benchsave/benchsave.go
index e5f857e..6474b61 100644
--- a/cmd/benchsave/benchsave.go
+++ b/cmd/benchsave/benchsave.go
@@ -102,7 +102,7 @@
start := time.Now()
- u := client.NewUpload()
+ u := client.NewUpload(context.Background())
for _, name := range files {
if err := writeOneFile(u, name, headerData); err != nil {
diff --git a/storage/client.go b/storage/client.go
index c734153..591d811 100644
--- a/storage/client.go
+++ b/storage/client.go
@@ -14,6 +14,8 @@
"net/http"
"net/url"
+ "golang.org/x/net/context"
+ "golang.org/x/net/context/ctxhttp"
"golang.org/x/perf/storage/benchfmt"
)
@@ -41,10 +43,10 @@
// key:value - exact match on label "key" = "value"
// key>value - value greater than (useful for dates)
// key<value - value less than (also useful for dates)
-func (c *Client) Query(q string) *Query {
+func (c *Client) Query(ctx context.Context, q string) *Query {
hc := c.httpClient()
- resp, err := hc.Get(c.BaseURL + "/search?" + url.Values{"q": []string{q}}.Encode())
+ resp, err := ctxhttp.Get(ctx, hc, c.BaseURL+"/search?"+url.Values{"q": []string{q}}.Encode())
if err != nil {
return &Query{err: err}
}
@@ -124,7 +126,7 @@
// extraLabels specifies other labels to be retrieved.
// If limit is 0, no limit will be provided to the server.
// The uploads are returned starting with the most recent upload.
-func (c *Client) ListUploads(q string, extraLabels []string, limit int) *UploadList {
+func (c *Client) ListUploads(ctx context.Context, q string, extraLabels []string, limit int) *UploadList {
hc := c.httpClient()
v := url.Values{"extra_label": extraLabels}
@@ -139,7 +141,7 @@
if len(v) > 0 {
u += "?" + v.Encode()
}
- resp, err := hc.Get(u)
+ resp, err := ctxhttp.Get(ctx, hc, u)
if err != nil {
return &UploadList{err: err}
}
@@ -213,7 +215,7 @@
// NewUpload starts a new upload to the storage server.
// The upload must have Abort or Commit called on it.
// If the server requires authentication for uploads, c.HTTPClient should be set to the result of oauth2.NewClient.
-func (c *Client) NewUpload() *Upload {
+func (c *Client) NewUpload(ctx context.Context) *Upload {
hc := c.httpClient()
pr, pw := io.Pipe()
@@ -228,7 +230,7 @@
errCh := make(chan error)
u := &Upload{pw: pw, mpw: mpw, errCh: errCh}
go func() {
- resp, err := hc.Do(req)
+ resp, err := ctxhttp.Do(ctx, hc, req)
if err != nil {
errCh <- err
return
diff --git a/storage/client_test.go b/storage/client_test.go
index ee327a7..6e5b87e 100644
--- a/storage/client_test.go
+++ b/storage/client_test.go
@@ -14,6 +14,7 @@
"reflect"
"testing"
+ "golang.org/x/net/context"
"golang.org/x/perf/internal/diff"
"golang.org/x/perf/storage/benchfmt"
)
@@ -26,7 +27,7 @@
c := &Client{BaseURL: ts.URL}
- q := c.Query("invalid query")
+ q := c.Query(context.Background(), "invalid query")
defer q.Close()
if q.Next() {
@@ -48,7 +49,7 @@
c := &Client{BaseURL: ts.URL}
- q := c.Query("key1:value key2:value")
+ q := c.Query(context.Background(), "key1:value key2:value")
defer q.Close()
var buf bytes.Buffer
@@ -79,7 +80,7 @@
c := &Client{BaseURL: ts.URL}
- r := c.ListUploads("key1:value key2:value", []string{"key1", "key2"}, 10)
+ r := c.ListUploads(context.Background(), "key1:value key2:value", []string{"key1", "key2"}, 10)
defer r.Close()
if !r.Next() {
@@ -132,7 +133,7 @@
c := &Client{BaseURL: ts.URL}
- u := c.NewUpload()
+ u := c.NewUpload(context.Background())
for i := 0; i < 2; i++ {
w, err := u.CreateFile(fmt.Sprintf("want%d.txt", i))
if err != nil {
@@ -190,7 +191,7 @@
c := &Client{BaseURL: ts.URL}
- u := c.NewUpload()
+ u := c.NewUpload(context.Background())
for i := 0; i < 2; i++ {
w, err := u.CreateFile(fmt.Sprintf("want%d.txt", i))
if err != nil {