Skip to content

Commit 84ee51b

Browse files
committed
[IMP] queue_job_batch: Add batch execution_time field.
This also adds an _on_finished hook that retries until the entire batch is complete.
1 parent 879d1a7 commit 84ee51b

5 files changed

Lines changed: 63 additions & 1 deletion

File tree

queue_job_batch/models/queue_job.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def write(self, vals):
2525
for record in self:
2626
if record.state != "done" and record.job_batch_id:
2727
batches |= record.job_batch_id
28-
for batch in batches:
28+
for batch in batches.with_context(job_batch=None):
2929
# We need to make it with delay in order to prevent two jobs
3030
# to work with the same batch
3131
batch.with_delay(identity_key=identity_exact).check_state()

queue_job_batch/models/queue_job_batch.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from odoo import api, fields, models
66

77
from odoo.addons.mail.tools.discuss import Store
8+
from odoo.addons.queue_job.exception import RetryableJobError
89

910

1011
class QueueJobBatch(models.Model):
@@ -58,6 +59,7 @@ class QueueJobBatch(models.Model):
5859
completeness = fields.Float(
5960
compute="_compute_job_count",
6061
)
62+
execution_time = fields.Float(compute="_compute_job_count")
6163
failed_percentage = fields.Float(
6264
compute="_compute_job_count",
6365
)
@@ -107,8 +109,13 @@ def _compute_job_count(self):
107109
rec.failed_job_count = len(jobs_by_state.get("failed", []))
108110
rec.finished_job_count = len(jobs_by_state.get("done", []))
109111
rec.completeness = rec.finished_job_count / max(1, rec.job_count)
112+
rec.execution_time = sum(rec.job_ids.mapped("exec_time"))
110113
rec.failed_percentage = rec.failed_job_count / max(1, rec.job_count)
111114

115+
def _on_finished(self):
116+
if self.state != "finished":
117+
raise RetryableJobError(f"{self.name} {100.0 * self.completeness}%")
118+
112119
@api.model
113120
def _to_store_fnames(self):
114121
return (

queue_job_batch/tests/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import test_queue_job_batch
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
2+
3+
from odoo.tests import TransactionCase
4+
5+
from odoo.addons.queue_job.exception import RetryableJobError
6+
7+
8+
class TestJobBatch(TransactionCase):
9+
def setUp(self):
10+
super().setUp()
11+
self.job_batch = self.env["queue.job.batch"].create(
12+
{
13+
"name": "test",
14+
"user_id": self.env.user.id,
15+
}
16+
)
17+
partners = self.env.ref("base.res_partner_1") + self.env.ref(
18+
"base.res_partner_2"
19+
)
20+
self.jobs = [
21+
p.with_context(job_batch=self.job_batch).with_delay()._get_complete_name()
22+
for p in partners
23+
]
24+
self.assertEqual(len(self.job_batch.job_ids), len(self.jobs))
25+
26+
def test_execution_time(self):
27+
self.assertEqual(self.job_batch.execution_time, 0)
28+
for job in self.jobs:
29+
job.set_started()
30+
job.perform()
31+
job.set_done()
32+
job.store()
33+
self.assertGreater(job.exec_time, 0)
34+
self.assertEqual(
35+
self.job_batch.execution_time,
36+
self.jobs[0].exec_time + self.jobs[1].exec_time,
37+
)
38+
39+
def test_on_finished(self):
40+
self.jobs[0].set_started()
41+
self.jobs[0].perform()
42+
self.jobs[0].set_done()
43+
self.jobs[0].store()
44+
self.assertEqual(self.job_batch.state, "pending")
45+
with self.assertRaises(RetryableJobError):
46+
self.job_batch._on_finished()
47+
self.jobs[1].set_started()
48+
self.jobs[1].perform()
49+
self.jobs[1].set_done()
50+
self.jobs[1].store()
51+
self.job_batch.check_state() # normally invoked with_delay
52+
self.assertEqual(self.job_batch.state, "finished")
53+
self.job_batch._on_finished()

queue_job_batch/views/queue_job_batch_views.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
options="{'current_value': 'finished_job_count', 'max_value': 'job_count'}"
1515
/>
1616
<field name="state" />
17+
<field name="execution_time" />
1718
</list>
1819
</field>
1920
</record>

0 commit comments

Comments
 (0)