internal/worker: use batch upload for compare mode
This is expected to resolve some bigquery "too much write" errors and it
refactors some code.
Change-Id: I69d8f4fdf5b449773bc37b98aaa2042cb971952d
Reviewed-on: https://go-review.googlesource.com/c/pkgsite-metrics/+/521055
Reviewed-by: Maceo Thompson <maceothompson@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Zvonimir Pavlinovic <zpavlinovic@google.com>
diff --git a/internal/worker/govulncheck_scan.go b/internal/worker/govulncheck_scan.go
index dd16d14..8f49a85 100644
--- a/internal/worker/govulncheck_scan.go
+++ b/internal/worker/govulncheck_scan.go
@@ -229,6 +229,8 @@
return nil
}
log.Infof(ctx, "scanner.runGovulncheckCompare found %d compilable binaries in %s:", len(response.FindingsForMod), sreq.Path())
+
+ var rows []bigquery.Row
for pkg, results := range response.FindingsForMod {
if results.Error != nil {
// Just log error if binary failed to build. Otherwise, we'd have
@@ -239,17 +241,13 @@
binRow := createComparisonRow(pkg, &results.BinaryResults, baseRow, ModeBinary)
srcRow := createComparisonRow(pkg, &results.SourceResults, baseRow, ModeGovulncheck)
-
log.Infof(ctx, "found %d vulns in binary mode and %d vulns in source mode for package %s (module: %s)", len(binRow.Vulns), len(srcRow.Vulns), pkg, sreq.Path())
-
- if err := writeResult(ctx, sreq.Serve, w, s.bqClient, govulncheck.TableName, binRow); err != nil {
- return err
- }
- if err := writeResult(ctx, sreq.Serve, w, s.bqClient, govulncheck.TableName, srcRow); err != nil {
- return err
- }
+ rows = append(rows, binRow, srcRow)
}
+ if len(rows) > 0 {
+ return writeResults(ctx, sreq.Serve, w, s.bqClient, govulncheck.TableName, rows)
+ }
return nil
}
diff --git a/internal/worker/scan.go b/internal/worker/scan.go
index 06f1186..caec509 100644
--- a/internal/worker/scan.go
+++ b/internal/worker/scan.go
@@ -158,16 +158,7 @@
if serve {
// Write the result to the client instead of uploading to BigQuery.
- log.Infof(ctx, "serving result to client")
- data, err := json.MarshalIndent(row, "", " ")
- if err != nil {
- return fmt.Errorf("marshaling result: %w", err)
- }
- _, err = w.Write(data)
- if err != nil {
- log.Errorf(ctx, err, "writing to client")
- }
- return nil // No point serving an error, the write already happened.
+ return serveJSON(ctx, row, w)
}
// Upload to BigQuery.
if client == nil {
@@ -177,6 +168,34 @@
return client.Upload(ctx, table, row)
}
+func writeResults(ctx context.Context, serve bool, w http.ResponseWriter, client *bigquery.Client, table string, rows []bigquery.Row) (err error) {
+ defer derrors.Wrap(&err, "writeResults")
+
+ if serve {
+ // Write the results to the client instead of uploading to BigQuery.
+ return serveJSON(ctx, rows, w)
+ }
+ // Upload to BigQuery.
+ if client == nil {
+ log.Infof(ctx, "bigquery disabled, not uploading")
+ return nil
+ }
+ return bigquery.UploadMany(ctx, client, table, rows, 0)
+}
+
+func serveJSON(ctx context.Context, content interface{}, w http.ResponseWriter) error {
+ log.Infof(ctx, "serving result to client")
+ data, err := json.MarshalIndent(content, "", " ")
+ if err != nil {
+ return fmt.Errorf("marshaling result: %w", err)
+ }
+ _, err = w.Write(data)
+ if err != nil {
+ log.Errorf(ctx, err, "writing to client")
+ }
+ return nil // No point serving an error, the write already happened.
+}
+
type openFileFunc func(filename string) (io.ReadCloser, error)
// copyToLocalFile opens destPath for writing locally, making it executable if specified.