Skip to content

Commit c480e9e

Browse files
committed
Merge PR #305 into 13.0
Signed-off-by simahawk
2 parents 56b56f4 + bb88d1e commit c480e9e

4 files changed

Lines changed: 65 additions & 93 deletions

File tree

queue_job/controllers/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ def retry_postpone(job, message, seconds=None):
113113

114114
@http.route("/queue_job/create_test_job", type="http", auth="user")
115115
def create_test_job(
116-
self, priority=None, max_retries=None, channel="root", description="Test job"
116+
self, priority=None, max_retries=None, channel=None, description="Test job"
117117
):
118118
if not http.request.env.user.has_group("base.group_erp_manager"):
119119
raise Forbidden(_("Access Denied"))

queue_job/job.py

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -441,13 +441,7 @@ def __init__(
441441
self.job_model_name = "queue.job"
442442

443443
self.job_config = (
444-
self.env["queue.job.function"]
445-
.sudo()
446-
.job_config(
447-
self.env["queue.job.function"].job_function_name(
448-
self.model_name, self.method_name
449-
)
450-
)
444+
self.env["queue.job.function"].sudo().job_config(self.job_function_name)
451445
)
452446

453447
self.state = PENDING
@@ -560,27 +554,35 @@ def store(self):
560554
if db_record:
561555
db_record.with_context(_job_edit_sentinel=edit_sentinel).write(vals)
562556
else:
563-
date_created = self.date_created
564-
# The following values must never be modified after the
565-
# creation of the job
566557
vals.update(
567558
{
559+
"user_id": self.env.uid,
560+
"channel": self.channel,
561+
# The following values must never be modified after the
562+
# creation of the job
568563
"uuid": self.uuid,
569564
"name": self.description,
570-
"date_created": date_created,
565+
"func_string": self.func_string,
566+
"date_created": self.date_created,
567+
"model_name": self.recordset._name,
571568
"method_name": self.method_name,
569+
"job_function_id": self.job_config.job_function_id,
570+
"channel_method_name": self.job_function_name,
572571
"records": self.recordset,
573572
"args": self.args,
574573
"kwargs": self.kwargs,
575574
}
576575
)
577-
# it the channel is not specified, lets the job_model compute
578-
# the right one to use
579-
if self.channel:
580-
vals.update({"channel": self.channel})
581-
582576
job_model.with_context(_job_edit_sentinel=edit_sentinel).sudo().create(vals)
583577

578+
@property
579+
def func_string(self):
580+
model = repr(self.recordset)
581+
args = [repr(arg) for arg in self.args]
582+
kwargs = ["{}={!r}".format(key, val) for key, val in self.kwargs.items()]
583+
all_args = ", ".join(args + kwargs)
584+
return "{}.{}({})".format(model, self.method_name, all_args)
585+
584586
def db_record(self):
585587
return self.db_record_from_uuid(self.env, self.uuid)
586588

@@ -589,6 +591,11 @@ def func(self):
589591
recordset = self.recordset.with_context(job_uuid=self.uuid)
590592
return getattr(recordset, self.method_name)
591593

594+
@property
595+
def job_function_name(self):
596+
func_model = self.env["queue.job.function"].sudo()
597+
return func_model.job_function_name(self.recordset._name, self.method_name)
598+
592599
@property
593600
def identity_key(self):
594601
if self._identity_key is None:
@@ -646,6 +653,14 @@ def eta(self, value):
646653
else:
647654
self._eta = value
648655

656+
@property
657+
def channel(self):
658+
return self._channel or self.job_config.channel
659+
660+
@channel.setter
661+
def channel(self, value):
662+
self._channel = value
663+
649664
def set_pending(self, result=None, reset_retry=True):
650665
self.state = PENDING
651666
self.date_enqueued = None

queue_job/models/queue_job.py

Lines changed: 31 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -43,27 +43,22 @@ class QueueJob(models.Model):
4343
"date_created",
4444
"model_name",
4545
"method_name",
46+
"func_string",
47+
"channel_method_name",
48+
"job_function_id",
4649
"records",
4750
"args",
4851
"kwargs",
4952
)
5053

5154
uuid = fields.Char(string="UUID", readonly=True, index=True, required=True)
52-
user_id = fields.Many2one(
53-
comodel_name="res.users",
54-
string="User ID",
55-
compute="_compute_user_id",
56-
inverse="_inverse_user_id",
57-
store=True,
58-
)
55+
user_id = fields.Many2one(comodel_name="res.users", string="User ID")
5956
company_id = fields.Many2one(
6057
comodel_name="res.company", string="Company", index=True
6158
)
6259
name = fields.Char(string="Description", readonly=True)
6360

64-
model_name = fields.Char(
65-
string="Model", compute="_compute_model_name", store=True, readonly=True
66-
)
61+
model_name = fields.Char(string="Model", readonly=True)
6762
method_name = fields.Char(readonly=True)
6863
# record_ids field is only for backward compatibility (e.g. used in related
6964
# actions), can be removed (replaced by "records") in 14.0
@@ -73,9 +68,7 @@ class QueueJob(models.Model):
7368
)
7469
args = JobSerialized(readonly=True, base_type=tuple)
7570
kwargs = JobSerialized(readonly=True, base_type=dict)
76-
func_string = fields.Char(
77-
string="Task", compute="_compute_func_string", readonly=True, store=True
78-
)
71+
func_string = fields.Char(string="Task", readonly=True)
7972

8073
state = fields.Selection(STATES, readonly=True, required=True, index=True)
8174
priority = fields.Integer()
@@ -95,21 +88,13 @@ class QueueJob(models.Model):
9588
"max. retries.\n"
9689
"Retries are infinite when empty.",
9790
)
98-
channel_method_name = fields.Char(
99-
readonly=True, compute="_compute_job_function", store=True
100-
)
91+
# FIXME the name of this field is very confusing
92+
channel_method_name = fields.Char(readonly=True)
10193
job_function_id = fields.Many2one(
102-
comodel_name="queue.job.function",
103-
compute="_compute_job_function",
104-
string="Job Function",
105-
readonly=True,
106-
store=True,
94+
comodel_name="queue.job.function", string="Job Function", readonly=True,
10795
)
10896

109-
override_channel = fields.Char()
110-
channel = fields.Char(
111-
compute="_compute_channel", inverse="_inverse_channel", store=True, index=True
112-
)
97+
channel = fields.Char(index=True)
11398

11499
identity_key = fields.Char(readonly=True)
115100
worker_pid = fields.Integer(readonly=True)
@@ -126,65 +111,18 @@ def init(self):
126111
"'enqueued') AND identity_key IS NOT NULL;"
127112
)
128113

129-
@api.depends("records")
130-
def _compute_user_id(self):
131-
for record in self:
132-
record.user_id = record.records.env.uid
133-
134-
def _inverse_user_id(self):
135-
for record in self.with_context(_job_edit_sentinel=self.EDIT_SENTINEL):
136-
record.records = record.records.with_user(record.user_id.id)
137-
138-
@api.depends("records")
139-
def _compute_model_name(self):
140-
for record in self:
141-
record.model_name = record.records._name
142-
143114
@api.depends("records")
144115
def _compute_record_ids(self):
145116
for record in self:
146117
record.record_ids = record.records.ids
147118

148-
def _inverse_channel(self):
149-
for record in self:
150-
record.override_channel = record.channel
151-
152-
@api.depends("job_function_id.channel_id")
153-
def _compute_channel(self):
154-
for record in self:
155-
channel = (
156-
record.override_channel or record.job_function_id.channel or "root"
157-
)
158-
if record.channel != channel:
159-
record.channel = channel
160-
161-
@api.depends("model_name", "method_name", "job_function_id.channel_id")
162-
def _compute_job_function(self):
163-
for record in self:
164-
func_model = self.env["queue.job.function"]
165-
channel_method_name = func_model.job_function_name(
166-
record.model_name, record.method_name
167-
)
168-
function = func_model.search([("name", "=", channel_method_name)], limit=1)
169-
record.channel_method_name = channel_method_name
170-
record.job_function_id = function
171-
172-
@api.depends("model_name", "method_name", "records", "args", "kwargs")
173-
def _compute_func_string(self):
174-
for record in self:
175-
model = repr(record.records)
176-
args = [repr(arg) for arg in record.args]
177-
kwargs = ["{}={!r}".format(key, val) for key, val in record.kwargs.items()]
178-
all_args = ", ".join(args + kwargs)
179-
record.func_string = "{}.{}({})".format(model, record.method_name, all_args)
180-
181119
@api.model_create_multi
182120
def create(self, vals_list):
183121
if self.env.context.get("_job_edit_sentinel") is not self.EDIT_SENTINEL:
184122
# Prevent to create a queue.job record "raw" from RPC.
185123
# ``with_delay()`` must be used.
186124
raise exceptions.AccessError(
187-
_("Queue jobs must created by calling 'with_delay()'.")
125+
_("Queue jobs must be created by calling 'with_delay()'.")
188126
)
189127
return super().create(vals_list)
190128

@@ -200,10 +138,25 @@ def write(self, vals):
200138
)
201139
)
202140

141+
different_user_jobs = self.browse()
142+
if vals.get("user_id"):
143+
different_user_jobs = self.filtered(
144+
lambda records: records.env.user.id != vals["user_id"]
145+
)
146+
203147
if vals.get("state") == "failed":
204148
self._message_post_on_failure()
205149

206-
return super().write(vals)
150+
result = super().write(vals)
151+
152+
for record in different_user_jobs:
153+
# the user is stored in the env of the record, but we still want to
154+
# have a stored user_id field to be able to search/groupby, so
155+
# synchronize the env of records with user_id
156+
super(QueueJob, record).write(
157+
{"records": record.records.with_user(vals["user_id"])}
158+
)
159+
return result
207160

208161
def open_related_action(self):
209162
"""Open the related action associated to the job"""
@@ -515,7 +468,8 @@ class JobFunction(models.Model):
515468
"retry_pattern "
516469
"related_action_enable "
517470
"related_action_func_name "
518-
"related_action_kwargs ",
471+
"related_action_kwargs "
472+
"job_function_id ",
519473
)
520474

521475
def _default_channel(self):
@@ -637,6 +591,7 @@ def job_default_config(self):
637591
related_action_enable=True,
638592
related_action_func_name=None,
639593
related_action_kwargs={},
594+
job_function_id=None,
640595
)
641596

642597
def _parse_retry_pattern(self):
@@ -669,6 +624,7 @@ def job_config(self, name):
669624
related_action_enable=config.related_action.get("enable", True),
670625
related_action_func_name=config.related_action.get("func_name"),
671626
related_action_kwargs=config.related_action.get("kwargs"),
627+
job_function_id=config.id,
672628
)
673629

674630
def _retry_pattern_format_error_message(self):

queue_job/tests/test_model_job_function.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def test_function_job_config(self):
3131
channel = self.env["queue.job.channel"].create(
3232
{"name": "foo", "parent_id": self.env.ref("queue_job.channel_root").id}
3333
)
34-
self.env["queue.job.function"].create(
34+
job_function = self.env["queue.job.function"].create(
3535
{
3636
"model_id": self.env.ref("base.model_res_users").id,
3737
"method": "read",
@@ -52,5 +52,6 @@ def test_function_job_config(self):
5252
related_action_enable=True,
5353
related_action_func_name="related_action_foo",
5454
related_action_kwargs={"b": 1},
55+
job_function_id=job_function.id,
5556
),
5657
)

0 commit comments

Comments
 (0)