From 77d6da1d83ed26d84952e683614a06e88e2f63c7 Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Tue, 10 Sep 2024 09:52:51 +0200 Subject: [PATCH] [IMP] queue_job: Adapt code after backporting improvements --- queue_job/__manifest__.py | 1 + queue_job/models/queue_job.py | 2 +- queue_job/models/queue_job_function.py | 38 +++++++++++++++++-- queue_job/wizards/__init__.py | 1 + queue_job/wizards/queue_jobs_to_cancelled.py | 17 +++++++++ .../wizards/queue_jobs_to_cancelled_views.xml | 34 +++++++++++++++++ test_queue_job/tests/test_job_auto_delay.py | 2 +- 7 files changed, 90 insertions(+), 5 deletions(-) create mode 100644 queue_job/wizards/queue_jobs_to_cancelled.py create mode 100644 queue_job/wizards/queue_jobs_to_cancelled_views.xml diff --git a/queue_job/__manifest__.py b/queue_job/__manifest__.py index 8afd327769..fbbb990860 100644 --- a/queue_job/__manifest__.py +++ b/queue_job/__manifest__.py @@ -19,6 +19,7 @@ "views/queue_job_function_views.xml", "wizards/queue_jobs_to_done_views.xml", "wizards/queue_requeue_job_views.xml", + "wizards/queue_jobs_to_cancelled_views.xml", "views/queue_job_menus.xml", "data/queue_data.xml", "data/queue_job_function_data.xml", diff --git a/queue_job/models/queue_job.py b/queue_job/models/queue_job.py index 8613c084de..c04c180cbb 100644 --- a/queue_job/models/queue_job.py +++ b/queue_job/models/queue_job.py @@ -1,6 +1,6 @@ # Copyright 2013-2020 Camptocamp SA # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html) - +import random import logging from datetime import datetime, timedelta diff --git a/queue_job/models/queue_job_function.py b/queue_job/models/queue_job_function.py index 023e26013e..47514251e1 100644 --- a/queue_job/models/queue_job_function.py +++ b/queue_job/models/queue_job_function.py @@ -27,7 +27,8 @@ class QueueJobFunction(models.Model): "retry_pattern " "related_action_enable " "related_action_func_name " - "related_action_kwargs ", + "related_action_kwargs " + "job_function_id ", ) def _default_channel(self): @@ -88,8 +89,8 @@ def _inverse_name(self): groups = regex_job_function_name.match(self.name) if not groups: raise exceptions.UserError(_("Invalid job function: {}").format(self.name)) - model_name = groups[1] - method = groups[2] + model_name = groups.group(1) + method = groups.group(2) model = self.env["ir.model"].search([("model", "=", model_name)], limit=1) if not model: raise exceptions.UserError(_("Model {} not found").format(model_name)) @@ -123,6 +124,29 @@ def _inverse_edit_related_action(self): def job_function_name(model_name, method_name): return "<{}>.{}".format(model_name, method_name) + @api.model + def _find_or_create_channel(self, channel_path): + channel_model = self.env['queue.job.channel'] + parts = channel_path.split('.') + parts.reverse() + channel_name = parts.pop() + assert channel_name == 'root', "A channel path starts with 'root'" + # get the root channel + channel = channel_model.search([('name', '=', channel_name)]) + while parts: + channel_name = parts.pop() + parent_channel = channel + channel = channel_model.search([ + ('name', '=', channel_name), + ('parent_id', '=', parent_channel.id), + ], limit=1) + if not channel: + channel = channel_model.create({ + 'name': channel_name, + 'parent_id': parent_channel.id, + }) + return channel + def job_default_config(self): return self.JobConfig( channel="root", @@ -130,6 +154,7 @@ def job_default_config(self): related_action_enable=True, related_action_func_name=None, related_action_kwargs={}, + job_function_id=None, ) def _parse_retry_pattern(self): @@ -162,6 +187,7 @@ def job_config(self, name): related_action_enable=config.related_action.get("enable", True), related_action_func_name=config.related_action.get("func_name"), related_action_kwargs=config.related_action.get("kwargs"), + job_function_id=config.id, ) def _retry_pattern_format_error_message(self): @@ -240,3 +266,9 @@ def unlink(self): res = super().unlink() self.clear_caches() return res + + def _register_job(self, model, job_method): + func_name = self.job_function_name(model._name, job_method.__name__) + if not self.search_count([('name', '=', func_name)]): + channel = self._find_or_create_channel(job_method.default_channel) + self.create({'name': func_name, 'channel_id': channel.id}) diff --git a/queue_job/wizards/__init__.py b/queue_job/wizards/__init__.py index 0794047e75..06c0bd8572 100644 --- a/queue_job/wizards/__init__.py +++ b/queue_job/wizards/__init__.py @@ -1,2 +1,3 @@ from . import queue_requeue_job from . import queue_jobs_to_done +from . import queue_jobs_to_cancelled diff --git a/queue_job/wizards/queue_jobs_to_cancelled.py b/queue_job/wizards/queue_jobs_to_cancelled.py new file mode 100644 index 0000000000..422290fe48 --- /dev/null +++ b/queue_job/wizards/queue_jobs_to_cancelled.py @@ -0,0 +1,17 @@ +# Copyright 2013-2020 Camptocamp SA +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html) + +from odoo import models + + +class SetJobsToCancelled(models.TransientModel): + _inherit = "queue.requeue.job" + _name = "queue.jobs.to.cancelled" + _description = "Cancel all selected jobs" + + def set_cancelled(self): + jobs = self.job_ids.filtered( + lambda x: x.state in ("pending", "failed", "enqueued") + ) + jobs.button_cancelled() + return {"type": "ir.actions.act_window_close"} \ No newline at end of file diff --git a/queue_job/wizards/queue_jobs_to_cancelled_views.xml b/queue_job/wizards/queue_jobs_to_cancelled_views.xml new file mode 100644 index 0000000000..da3e7a077c --- /dev/null +++ b/queue_job/wizards/queue_jobs_to_cancelled_views.xml @@ -0,0 +1,34 @@ + + + + + Cancel Jobs + queue.jobs.to.cancelled + +
+ + + +
+
+
+
+
+ + + Cancel jobs + queue.jobs.to.cancelled + form + + new + + + +
diff --git a/test_queue_job/tests/test_job_auto_delay.py b/test_queue_job/tests/test_job_auto_delay.py index 5549fc7487..8e6f40c696 100644 --- a/test_queue_job/tests/test_job_auto_delay.py +++ b/test_queue_job/tests/test_job_auto_delay.py @@ -34,7 +34,7 @@ def test_auto_delay_force_sync(self): """method forced to run synchronously""" result = ( self.env["test.queue.job"] - .with_context(_job_force_sync=True) + .with_context(queue_job__no_delay=True) .delay_me(1, kwarg=2) ) self.assertTrue(result, (1, 2))