Skip to content

Commit f88aa22

Browse files
committed
[IMP] enhance queue job tracking and prevent concurrent operations
1 parent 7a7314a commit f88aa22

File tree

3 files changed

+105
-21
lines changed

3 files changed

+105
-21
lines changed

spp_demo_common/CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22

33
## 2025-11-20
44

5+
### 2025-11-20 15:45:00 - [IMP] enhance queue job tracking and prevent concurrent operations
6+
7+
- Added `has_ongoing_jobs` computed field to detect concurrent job operations
8+
- Added `ongoing_job_generator_id` computed field to identify which generator has ongoing jobs
9+
- Combined compute logic into single efficient method `_compute_ongoing_jobs_info()`
10+
- Enhanced Queue Jobs page with state decorations, detailed form view, and exception information
11+
- Added info alert banner to notify users when another generator is running
12+
- Hidden Generate button when any generator has ongoing jobs to prevent race conditions
13+
514
### 2025-11-20 14:30:00 - [ADD] track queue jobs in demo data generator
615

716
- Added `queue_job_ids` computed field to link queue jobs to demo data generator records

spp_demo_common/models/demo_data_generator.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
from faker import Faker
88

9-
from odoo import fields, models
9+
from odoo import api, fields, models
1010
from odoo.exceptions import ValidationError
1111

1212
from odoo.addons.queue_job.delay import group
@@ -120,6 +120,17 @@ def _default_queue_job_minimum_size(self):
120120
string="Queue Jobs",
121121
compute="_compute_queue_job_count",
122122
)
123+
has_ongoing_jobs = fields.Boolean(
124+
compute="_compute_ongoing_jobs_info",
125+
string="Has Ongoing Jobs",
126+
help="True if there are any ongoing queue jobs for this model",
127+
)
128+
ongoing_job_generator_id = fields.Many2one(
129+
"spp.demo.data.generator",
130+
compute="_compute_ongoing_jobs_info",
131+
string="Generator with Ongoing Jobs",
132+
help="Demo data generator record that currently has ongoing jobs",
133+
)
123134

124135
def _compute_generation_log_count(self):
125136
for rec in self:
@@ -138,6 +149,31 @@ def _compute_queue_job_count(self):
138149
for rec in self:
139150
rec.queue_job_count = len(rec.queue_job_ids)
140151

152+
@api.depends("queue_job_ids", "queue_job_ids.state")
153+
def _compute_ongoing_jobs_info(self):
154+
"""
155+
Compute both has_ongoing_jobs and ongoing_job_generator_id fields.
156+
Checks for any ongoing jobs across ALL demo data generator records
157+
to prevent concurrent operations.
158+
"""
159+
# Find any ongoing job for this model
160+
ongoing_job = self.env["queue.job"].search(
161+
[
162+
("res_model", "=", "spp.demo.data.generator"),
163+
("state", "in", ["pending", "enqueued", "started"]),
164+
],
165+
limit=1,
166+
)
167+
168+
# Determine values based on job existence
169+
has_ongoing = bool(ongoing_job)
170+
generator_id = ongoing_job.res_id if ongoing_job and ongoing_job.res_id else None
171+
172+
# Set the same values for all records
173+
for rec in self:
174+
rec.has_ongoing_jobs = has_ongoing
175+
rec.ongoing_job_generator_id = generator_id
176+
141177
def generate_demo_data(self):
142178
self.ensure_one()
143179
faker_code = self.locale_origin.faker_locale or "en_US"

spp_demo_common/views/demo_data_generator_view.xml

Lines changed: 59 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
/>
3030
</header>
3131
<field name="locked" invisible="True" />
32+
<field name="has_ongoing_jobs" invisible="1" />
33+
<field name="ongoing_job_generator_id" invisible="1" />
3234
<div
3335
class="alert alert-warning text-center o_form_header"
3436
role="status"
@@ -45,6 +47,22 @@
4547
string="Refresh"
4648
/>
4749
</div>
50+
<div
51+
class="alert alert-info text-center o_form_header"
52+
role="status"
53+
invisible="not has_ongoing_jobs or id == ongoing_job_generator_id"
54+
>
55+
<span>Info: Another demo data generation is currently in progress: </span>
56+
<field name="ongoing_job_generator_id" class="o_stat_value" readonly="1" />
57+
<button
58+
name="refresh_page"
59+
type="object"
60+
class="btn-link"
61+
icon="fa-refresh"
62+
title="Refresh Page"
63+
string="Refresh"
64+
/>
65+
</div>
4866
<field name="locale_origin_faker_locale" invisible="1" />
4967
<div
5068
class="alert alert-warning text-center o_form_header"
@@ -63,7 +81,7 @@
6381
class="oe_stat_button"
6482
icon="fa-thumbs-o-up"
6583
name="generate_demo_data"
66-
invisible="state != 'draft'"
84+
invisible="state != 'draft' or has_ongoing_jobs"
6785
>
6886
<div class="o_form_field o_stat_info">
6987
<span class="o_stat_text">Generate</span>
@@ -302,27 +320,48 @@
302320
</form>
303321
</field>
304322
</page>
305-
<page string="Queue Jobs" invisible="not queue_job_ids">
306-
<field name="queue_job_count" invisible="1" />
307-
<group>
308-
<div class="alert alert-info" role="alert">
309-
<strong>Queue Jobs:</strong>
310-
<span>
311-
<field name="queue_job_count" readonly="1" />
312-
job(s) created for this generation
313-
</span>
314-
</div>
315-
</group>
316-
<field name="queue_job_ids" readonly="1">
317-
<tree create="false" edit="false" delete="false">
318-
<field name="date_created" string="Created" />
319-
<field name="date_started" string="Started" />
320-
<field name="date_enqueued" string="Enqueued" />
321-
<field name="date_done" string="Done" />
322-
<field name="state" />
323+
<page string="Queue Jobs" name="queue_jobs" invisible="not queue_job_ids">
324+
<field name="queue_job_ids" nolabel="1" readonly="1">
325+
<tree>
323326
<field name="method_name" />
324-
<field name="result" />
327+
<field
328+
name="state"
329+
decoration-info="state=='pending'"
330+
decoration-warning="state=='enqueued'"
331+
decoration-primary="state=='started'"
332+
decoration-success="state=='done'"
333+
decoration-danger="state=='failed'"
334+
widget="badge"
335+
/>
336+
<field name="date_created" />
337+
<field name="date_started" />
338+
<field name="date_done" />
339+
<field name="exc_info" />
325340
</tree>
341+
<form>
342+
<header>
343+
<field name="state" widget="statusbar" />
344+
</header>
345+
<group>
346+
<group>
347+
<field name="name" />
348+
<field name="model_name" />
349+
<field name="method_name" />
350+
<field name="res_model" />
351+
<field name="res_id" />
352+
</group>
353+
<group>
354+
<field name="date_created" />
355+
<field name="date_enqueued" />
356+
<field name="date_started" />
357+
<field name="date_done" />
358+
<field name="priority" />
359+
</group>
360+
</group>
361+
<group string="Exception Information" invisible="not exc_info">
362+
<field name="exc_info" nolabel="1" readonly="1" />
363+
</group>
364+
</form>
326365
</field>
327366
</page>
328367
</notebook>

0 commit comments

Comments
 (0)