Skip to content

feat: cancel a scan that is queued for a slot - #1246

Merged
crypt0rr merged 2 commits into
mainfrom
feat/cancel-queued-runs
Oct 7, 2026
Merged

crypt0rr merged 2 commits into
mainfrom
feat/cancel-queued-runs

Conversation

@crypt0rr

@crypt0rr crypt0rr commented Oct 7, 2026

Copy link
Copy Markdown
Owner

Summary

A run waiting for a scan slot can now be withdrawn (#1226). Before this change only a running scan could be cancelled, so an accidental Scan now behind a long scan, with max_concurrent_scans: 1, could not be taken back.

API

  • New route DELETE /jobs/{id}/run, using the same jobs.run permission as starting a run.
  • 202 {"status":"canceled"} when the job had a queued run.
  • 409 run_not_queued when nothing is waiting, including a run that has already taken its slot; a running scan is still cancelled with POST /scans/{id}/cancel.
  • Another unit's job resolves exactly like an unknown job (resolveJob), and TestIsolationMatrix covers the route automatically through apiRoutes.
  • Audited as scan.queued_run_canceled, in the data category.

App

  • Each queued run waits on its own child context (context.WithCancelCause), so CancelQueuedRun ends only the wait and never touches the run context the scan will use.
  • A small mutex-guarded started/canceled pair makes the race with the slot grant deterministic: a cancel either stops a run that hasn't taken its slot, or is refused because it has.
  • The withdrawn run returns ErrQueuedRunCanceled, never starts or holds a slot, and is reported as scan.skipped with the new reason canceled. A cancelled scheduled run is logged as skipped, not as scan failed.

Console

  • Cancel queued scan appears in the job page's "Scan queued" panel once the server reports the run as queued, and on each queued row of the Overview.
  • The skip event for a deliberate cancel closes the panel without an error banner.

Docs: the jobs guide describes Cancel queued scan.

Compatibility

Additive: a new route, a new skip reason canceled, and a new audit action. There are no schema changes.

Validation

  • gofmt, go vet ./...
  • go test -race for the queued and slot tests in internal/app, and for the new route, isolation, route-drift, permission and audit tests in internal/web. The audit-category tests in internal/store pass with the new action.
  • npm run lint
  • Vitest: 45 files passed.
  • npm --prefix docs run build

New tests:

  • internal/app/queued_cancel_test.go:
    • cancelling a queued manual run returns ErrQueuedRunCanceled, emits one canceled skip, takes no slot and persists no scan;
    • a scope without a unit, another unit's run, a run that has started, and a second cancel are each refused;
    • a cancel that lands as the slot is granted stops the run.
  • internal/web/scan_control_test.go: the route returns 202, then 409 run_not_queued for that job and for the running job, and leaves the running scan untouched.
  • Console: the job page cancel, no button before the server reports the run as queued, the Overview cancel, and an Overview refusal.

Fixes #1226

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Deploying edgewatch with  Cloudflare Pages  Cloudflare Pages

Latest commit: eec50ef
Status: ✅  Deploy successful!
Preview URL: https://926ed37b.edgewatch-cpd.pages.dev
Branch Preview URL: https://feat-cancel-queued-runs.edgewatch-cpd.pages.dev

View logs

@crypt0rr
crypt0rr force-pushed the feat/cancel-queued-runs branch from dde80c2 to eec50ef Compare October 7, 2026 16:35
A run waiting for a scan slot can be withdrawn with DELETE
/jobs/{id}/run (jobs.run) or the new Cancel queued scan button on the
job page and the Overview. The run's wait has its own context, so the
cancellation ends only the wait; a cancellation that races the slot
grant is refused for a run that has taken its slot and stops one that
has not. The withdrawn run is reported as scan.skipped with reason
canceled, is audited as scan.queued_run_canceled, and never starts or
holds a slot.

Fixes #1226
@crypt0rr
crypt0rr force-pushed the feat/cancel-queued-runs branch from eec50ef to 82c6e0c Compare October 7, 2026 17:01
@crypt0rr
crypt0rr merged commit 8c07447 into main Oct 7, 2026
15 checks passed
@crypt0rr
crypt0rr deleted the feat/cancel-queued-runs branch October 7, 2026 17:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[P3] A queued scan run cannot be cancelled

1 participant