internal/worker: support job cancellation
The analysis/scan endpoint checks if the job is canceled and stops
early if it is.
The jobs/cancel endpoint cancels a job.
Change-Id: I59a9b025b7ab0b3703175809bc798f76522fcfb5
Reviewed-on: https://go-review.googlesource.com/c/pkgsite-metrics/+/495796
Reviewed-by: Maceo Thompson <maceothompson@google.com>
Run-TryBot: Jonathan Amsterdam <jba@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
diff --git a/internal/worker/analysis.go b/internal/worker/analysis.go
index 05620c4..a56f991 100644
--- a/internal/worker/analysis.go
+++ b/internal/worker/analysis.go
@@ -74,6 +74,17 @@
return fmt.Errorf("%w: %v", derrors.InvalidArgument, err)
}
+ // If there is a job and it's canceled, return immediately.
+ if req.JobID != "" && s.jobDB != nil {
+ job, err := s.jobDB.GetJob(ctx, req.JobID)
+ if err != nil {
+ log.Errorf(ctx, err, "failed to get job for id %q", req.JobID)
+ } else if job.Canceled {
+ log.Infof(ctx, "job %q canceled; skipping", req.JobID)
+ return nil
+ }
+ }
+
// updateJob updates the job for this request if there is one.
// If there is an error, it logs it instead of failing.
updateJob := func(f func(*jobs.Job)) {
diff --git a/internal/worker/jobs.go b/internal/worker/jobs.go
index 1ec45b8..e9bbf94 100644
--- a/internal/worker/jobs.go
+++ b/internal/worker/jobs.go
@@ -60,6 +60,15 @@
enc.Encode(job)
return nil
+ case "/cancel":
+ if jobID == "" {
+ return fmt.Errorf("missing jobid: %w", derrors.InvalidArgument)
+ }
+ return db.UpdateJob(ctx, jobID, func(j *jobs.Job) error {
+ j.Canceled = true
+ return nil
+ })
+
default:
return fmt.Errorf("unknown path %q: %w", path, derrors.InvalidArgument)
}
diff --git a/internal/worker/jobs_test.go b/internal/worker/jobs_test.go
index a5ea704..806a30e 100644
--- a/internal/worker/jobs_test.go
+++ b/internal/worker/jobs_test.go
@@ -37,6 +37,18 @@
if !cmp.Equal(&got, job) {
t.Errorf("got\n%+v\nwant\n%+v", got, job)
}
+
+ if err := processJobRequest(ctx, &buf, "/cancel", job.ID(), db); err != nil {
+ t.Fatal(err)
+ }
+
+ got2, err := db.GetJob(ctx, job.ID())
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !got2.Canceled {
+ t.Error("got canceled false, want true")
+ }
}
type testJobDB struct {