Skip to content

Support cancelling a submission#75

Open
jerbaroo wants to merge 8 commits intomasterfrom
jerbaroo-43
Open

Support cancelling a submission#75
jerbaroo wants to merge 8 commits intomasterfrom
jerbaroo-43

Conversation

@jerbaroo
Copy link
Contributor

@jerbaroo jerbaroo commented Feb 26, 2026

This PR adds a new method cancel_submission to ProducerClient. This method takes a SubmissionId and returns None if successful. If the submission could not be found a SubmissionNotFoundError is raised. If the submission was already completed, failed or cancelled then a SubmissionNotCancellableError is raised which contains the specific reason.

@jerbaroo jerbaroo marked this pull request as ready for review February 27, 2026 15:40
@jerbaroo jerbaroo requested a review from Copilot February 27, 2026 15:43
@jerbaroo jerbaroo linked an issue Feb 27, 2026 that may be closed by this pull request
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds end-to-end support for cancelling an in-progress submission: it introduces a cancelled submission state persisted in a new submissions_cancelled table, exposes a new producer HTTP endpoint + Rust client method, and wires the feature through the Python bindings and tests.

Changes:

  • Add SubmissionStatus::Cancelled / SubmissionCancelled and a DB cancel path that moves submissions into submissions_cancelled.
  • Expose POST /producer/submissions/cancel/{submission_id} and a matching Client::cancel_submission method.
  • Add Python API + exceptions for cancellation and add roundtrip tests for cancel/not-found/not-cancellable cases.

Reviewed changes

Copilot reviewed 14 out of 16 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
opsqueue/src/prometheus.rs Adds metric names for cancelled submissions.
opsqueue/src/producer/server.rs Adds new HTTP route/handler for cancelling submissions.
opsqueue/src/producer/client.rs Adds client method to call the cancel endpoint and decode errors.
opsqueue/src/common/submission.rs Adds cancelled submission status, DB queries, cancel mutation, and cleanup logic.
opsqueue/src/common/errors.rs Adds serializable cancellation-related error types.
opsqueue/opsqueue_example_database_schema.db Adds an example SQLite schema DB file reflecting new tables.
opsqueue/migrations/20260225164600_submissions_cancelled.sql Adds migration creating submissions_cancelled.
libs/opsqueue_python/tests/test_roundtrip.py Adds Python integration tests for cancel behavior and exceptions.
libs/opsqueue_python/src/producer.rs Exposes cancel_submission from Rust -> Python client.
libs/opsqueue_python/src/lib.rs Registers new Python-exposed types (but see review comments).
libs/opsqueue_python/src/errors.rs Maps new cancellation errors into Python exceptions.
libs/opsqueue_python/src/common.rs Adds Python types for cancelled status and not-cancellable details.
libs/opsqueue_python/python/opsqueue/producer.py Adds Python ProducerClient.cancel_submission wrapper + docs.
libs/opsqueue_python/python/opsqueue/exceptions.py Adds Python SubmissionNotCancellableError and enriches SubmissionNotFoundError.
Cargo.toml Bumps workspace version to 0.35.0.
Cargo.lock Updates locked versions for opsqueue and opsqueue_python.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@jerbaroo jerbaroo requested a review from Qqwy February 27, 2026 16:07
@jerbaroo jerbaroo removed the request for review from Qqwy March 11, 2026 15:24
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 16 changed files in this pull request and generated 6 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

@jerbaroo jerbaroo requested a review from Qqwy March 17, 2026 15:55
describe_counter!(
SUBMISSIONS_CANCELLED_COUNTER,
Unit::Count,
"Number of submissions cancelled permanently"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Good to indicate here what the difference between cancelled and failed is, so people using the Prometheus metrics in Grafana will understand without having to look it up.

Copy link
Contributor

@Qqwy Qqwy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice work Jeremy! The main thing that's still missing (if I read it correctly) is a test case for the happy path. Besides that, I have a couple of smaller nits/remarks, but nothing big.

// 200 if the submission was successfully cancelled.
// 404 if the submission could not be found.
// 409 if the submission could not be cancelled.
// 500 if a DatabaseError occurred.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: If you turn this into /// comments, it will become part of the documentation (both for LSPs and if someone runs cargo doc)

As discussed face to face: It would be cleaner to encode these errors inside the data rather than in the transport layer, but since we control both the server and the client here this can be considered overkill. So let's Keep It Simple as it is now 👍.

E<
errors::SubmissionNotFound,
E<errors::SubmissionNotCancellable, InternalProducerClientError>,
>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: You can use the E![...] macro to make the return type a bit more readable here. See for example

query!(
"DELETE FROM submissions_metadata
WHERE submission_id = (
WHERE submission_id IN (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Pretty sure it was (only...) the leniency that SQLite has in certain places that made this work before.

submission = producer_client.get_submission_status(submission_id)
assert submission is not None
assert_submission_failed_has_metadata(submission.submission)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Am I overlooking something, or is there no test for the 'happy path' yet?

(Love the error case tests though! 👍)

.await
.map_err(|e| CError(R(e)))
})
// TODO ?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Left commented code with TODO

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.

Support canceling a submission

3 participants