Skip to content

[19.0] [FIX] queue_job: set date_cancelled on cancelled dependent jobs - #1015

Open
ivantodorovich wants to merge 1 commit into
OCA:19.0from
camptocamp:19.0-fix-queue_job-cancel-dependent-date
Open

ivantodorovich wants to merge 1 commit into
OCA:19.0from
camptocamp:19.0-fix-queue_job-cancel-dependent-date

Conversation

@ivantodorovich

@ivantodorovich ivantodorovich commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor
  • Cancellation now cascades. Cancelling a job used to cancel only its direct dependents: in A → B → C, cancelling A left C in wait_dependencies forever.
    Test: test_button_cancel_dependencies_cascade
  • A job is cancelled as soon as one of its dependencies is cancelled. It used to be cancelled only when all of them were, so a job with one cancelled and one done (or running) dependency waited forever.
    Tests: test_button_cancel_dependencies_other_parent_done, test_button_done_dependencies_other_parent_cancelled
  • Cancelled dependents get a date_cancelled, the same as the cancelled job. It was left empty, so the autovacuum never removed them.
    Tests: test_button_cancel_dependencies, test_button_cancel_dependencies_cascade
  • Cancelled dependents get a result telling why they were cancelled.
    Tests: test_button_cancel_dependencies_cascade, test_button_cancel_dependencies_selected
  • Cancelling a job along with its dependent cancels the dependent once. It used to be cancelled a second time as part of the selection, overwriting its date and result.
    Test: test_button_cancel_dependencies_selected

_get_common_dependent_jobs_query is replaced by the dependency_ids / dependent_ids computed fields on queue.job, used to enqueue and cancel dependent jobs through the ORM.

@OCA-git-bot

Copy link
Copy Markdown
Contributor

Hi @sbidoul, @guewen,
some modules you are maintaining are being modified, check this out!

@OCA-git-bot OCA-git-bot added series:19.0 mod:queue_job Module queue_job mod:test_queue_job Module test_queue_job labels Oct 20, 2026

@florentx florentx left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I would use same date_cancelled as parent job, and do it a little bit differently:

--- a/queue_job/job.py
+++ b/queue_job/job.py
@@ -545,10 +545,10 @@ class Job:
             finally:
                 self._env = env
 
-    def _get_common_dependent_jobs_query(self):
-        return """
+    def _get_common_dependent_jobs_query(self, sql_set_clause):
+        return f"""
             UPDATE queue_job
-            SET state = %s
+            SET {sql_set_clause}
             FROM (
             SELECT child.id, array_agg(parent.state) as parent_states
             FROM queue_job job
@@ -579,13 +579,15 @@ class Job:
         return any(self.__reverse_depends_on_uuids)
 
     def enqueue_waiting(self):
-        sql = self._get_common_dependent_jobs_query()
+        sql = self._get_common_dependent_jobs_query("state = %s")
         self.env.cr.execute(sql, (PENDING, self.uuid, DONE, WAIT_DEPENDENCIES))
         self.env["queue.job"].invalidate_model(["state"])
 
     def cancel_dependent_jobs(self):
-        sql = self._get_common_dependent_jobs_query()
-        self.env.cr.execute(sql, (CANCELLED, self.uuid, CANCELLED, WAIT_DEPENDENCIES))
+        assert self.state == CANCELLED, "Job is not cancelled"
+        sql = self._get_common_dependent_jobs_query("state = %s, date_cancelled = %s")
+        sql_args = (CANCELLED, self.date_cancelled, self.uuid, CANCELLED, WAIT_DEPENDENCIES)
+        self.env.cr.execute(sql, sql_args)
         self.env["queue.job"].invalidate_model(["state"])
 
     def store(self):

@ivantodorovich
ivantodorovich force-pushed the 19.0-fix-queue_job-cancel-dependent-date branch from 61d0bd3 to 6063e7d Compare October 22, 2026 13:38
- Cancelling a job now cancels its dependents all the way down. Before,
  only direct dependents were cancelled: in A -> B -> C, cancelling A
  left C waiting forever.
  Test: test_button_cancel_dependencies_cascade
- A job is cancelled as soon as one of its dependencies is cancelled.
  Before, it was only cancelled when all of them were, so a job with one
  cancelled and one done (or running) dependency waited forever.
  Tests: test_button_cancel_dependencies_other_parent_done,
  test_button_done_dependencies_other_parent_cancelled
- Cancelled dependents get a date_cancelled, the same as the cancelled
  job. It was left empty, so the autovacuum never removed them.
  Tests: test_button_cancel_dependencies,
  test_button_cancel_dependencies_cascade
- Cancelled dependents get a result telling why they were cancelled.
  Tests: test_button_cancel_dependencies_cascade,
  test_button_cancel_dependencies_selected
- Cancelling a job along with its dependent cancels the dependent once.
  Before, it was cancelled a second time as part of the selection,
  overwriting its date and result.
  Test: test_button_cancel_dependencies_selected

_get_common_dependent_jobs_query is replaced by the dependency_ids and
dependent_ids computed fields on queue.job, used to enqueue and cancel
dependent jobs through the ORM.
@ivantodorovich
ivantodorovich force-pushed the 19.0-fix-queue_job-cancel-dependent-date branch from 6063e7d to f073767 Compare October 22, 2026 13:53
@ivantodorovich

Copy link
Copy Markdown
Contributor Author

Hi @florentx

I digged a bit deeper and found other issues with the current implementation, all described in the PR description and covered by new unit tests. So I decided to refactor and use the orm and computed fields instead of this query.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mod:queue_job Module queue_job mod:test_queue_job Module test_queue_job series:19.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants