-
+
The fast way to enqueue a job for a method is to use with_delay() on a record
or model:
-def button_done(self):
+def button_done(self):
self.with_delay().print_confirmation_document(self.state)
self.write({"state": "done"})
return True
@@ -524,7 +530,7 @@
on a record or model. The following is the equivalent of with_delay() but using the
long form:
-def button_done(self):
+def button_done(self):
delayable = self.delayable()
delayable.print_confirmation_document(self.state)
delayable.delay()
@@ -534,7 +540,7 @@
Methods of Delayable objects return itself, so it can be used as a builder pattern,
which in some cases allow to build the jobs dynamically:
-def button_generate_simple_with_delayable(self):
+def button_generate_simple_with_delayable(self):
self.ensure_one()
# Introduction of a delayable object, using a builder pattern
# allowing to chain jobs or set properties. The delay() method
@@ -550,7 +556,7 @@
The simplest way to define a dependency is to use .on_done(job) on a Delayable:
-def button_chain_done(self):
+def button_chain_done(self):
self.ensure_one()
job1 = self.browse(1).delayable().generate_thumbnail((50, 50))
job2 = self.browse(1).delayable().generate_thumbnail((50, 50))
@@ -567,9 +573,9 @@
[B] of jobs. When and only when all the jobs of the group [A] are executed, the
jobs of the group [B] are executed. The code would look like:
-from odoo.addons.queue_job.delay import group, chain
+from odoo.addons.queue_job.delay import group, chain
-def button_done(self):
+def button_done(self):
group_a = group(self.delayable().method_foo(), self.delayable().method_bar())
group_b = group(self.delayable().method_baz(1), self.delayable().method_baz(2))
chain(group_a, group_b).delay()
@@ -588,7 +594,7 @@
would never be delayed (but a warning would be shown).
-
+
Asserting enqueued jobs
The recommended way to test jobs, rather than running them directly and synchronously is to
split the tests in two parts:
@@ -741,20 +747,20 @@
A very small example (more details in tests/common.py):
# code
-def my_job_method(self, name, count):
+def my_job_method(self, name, count):
self.write({"name": " ".join([name] * count)
-def method_to_test(self):
+def method_to_test(self):
count = self.env["other.model"].search_count([])
self.with_delay(priority=15).my_job_method("Hi!", count=count)
return count
# tests
-from odoo.addons.queue_job.tests.common import trap_jobs
+from odoo.addons.queue_job.tests.common import trap_jobs
# first test only check the expected behavior of the method and the proper
# enqueuing of jobs
-def test_method_to_test(self):
+def test_method_to_test(self):
with trap_jobs() as trap:
result = self.env["model"].method_to_test()
expected_count = 12
@@ -770,7 +776,7 @@
# second test to validate the behavior of the job unitarily
- def test_my_job_method(self):
+ def test_my_job_method(self):
record = self.env["model"].browse(1)
record.my_job_method("Hi!", count=12)
self.assertEqual(record.name, "Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi!")
@@ -778,7 +784,7 @@
If you prefer, you can still test the whole thing in a single test, by calling
jobs_tester.perform_enqueued_jobs() in your test.
-def test_method_to_test(self):
+def test_method_to_test(self):
with trap_jobs() as trap:
result = self.env["model"].method_to_test()
expected_count = 12
@@ -813,7 +819,7 @@
Tip: you can do this at test case level like this
@classmethod
-def setUpClass(cls):
+def setUpClass(cls):
super().setUpClass()
cls.env = cls.env(context=dict(
cls.env.context,
@@ -832,14 +838,14 @@