Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions queue_job/controllers/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,10 @@ def _prevent_commit(cr):
def forbidden_commit(*args, **kwargs):
raise RuntimeError(
"Commit is forbidden in queue jobs. "
"If the current job is a cron running as queue job, "
"modify it to run as a normal cron."
'You may want to enable the "Allow Commit" option on the Job '
"Function. Alternatively, if the current job is a cron running as "
"queue job, you can modify it to run as a normal cron. More details on: "
"https://github.com/OCA/queue/wiki/%5BDRAFT%5D-Upgrade-warning:-commits-inside-jobs"
)

original_commit = cr.commit
Expand Down
26 changes: 21 additions & 5 deletions queue_job/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import sys
import uuid
import weakref
from contextlib import contextmanager, nullcontext
from datetime import datetime, timedelta
from random import randint

Expand Down Expand Up @@ -406,10 +407,6 @@ def __init__(
self.method_name = func.__name__
self.recordset = recordset

self.env = env
self.job_model = self.env["queue.job"]
self.job_model_name = "queue.job"

self.job_config = (
self.env["queue.job.function"].sudo().job_config(self.job_function_name)
)
Expand Down Expand Up @@ -487,7 +484,12 @@ def perform(self):
"""
self.retry += 1
try:
self.result = self.func(*tuple(self.args), **self.kwargs)
if self.job_config.allow_commit:
env_context_manager = self._with_temporary_env()
else:
env_context_manager = nullcontext()
with env_context_manager:
self.result = self.func(*tuple(self.args), **self.kwargs)
except RetryableJobError as err:
if err.ignore_retry:
self.retry -= 1
Expand All @@ -507,6 +509,16 @@ def perform(self):

return self.result

@contextmanager
def _with_temporary_env(self):
with self.env.registry.cursor() as new_cr:
env = self.recordset.env
self.recordset = self.recordset.with_env(env(cr=new_cr))
try:
yield
finally:
self.recordset = self.recordset.with_env(env)

def _get_common_dependent_jobs_query(self):
return """
UPDATE queue_job
Expand Down Expand Up @@ -665,6 +677,10 @@ def __hash__(self):
def db_record(self):
return self.db_records_from_uuids(self.env, [self.uuid])

@property
def env(self):
return self.recordset.env

@property
def func(self):
recordset = self.recordset.with_context(job_uuid=self.uuid)
Expand Down
11 changes: 10 additions & 1 deletion queue_job/models/queue_job_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ class QueueJobFunction(models.Model):
"related_action_enable "
"related_action_func_name "
"related_action_kwargs "
"job_function_id ",
"job_function_id "
"allow_commit",
)

def _default_channel(self):
Expand Down Expand Up @@ -79,6 +80,12 @@ def _default_channel(self):
"enable, func_name, kwargs.\n"
"See the module description for details.",
)
allow_commit = fields.Boolean(
help="Allows the job to commit transactions during execution. "
"Under the hood, this executes the job in a new database cursor, "
"which incurs an overhead as it requires an extra connection to "
"the database. "
)

@api.depends("model_id.model", "method")
def _compute_name(self):
Expand Down Expand Up @@ -149,6 +156,7 @@ def job_default_config(self):
related_action_func_name=None,
related_action_kwargs={},
job_function_id=None,
allow_commit=False,
)

def _parse_retry_pattern(self):
Expand Down Expand Up @@ -184,6 +192,7 @@ def job_config(self, name):
related_action_func_name=config.related_action.get("func_name"),
related_action_kwargs=config.related_action.get("kwargs", {}),
job_function_id=config.id,
allow_commit=config.allow_commit,
)

def _retry_pattern_format_error_message(self):
Expand Down
2 changes: 1 addition & 1 deletion queue_job/tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ def _add_job(self, *args, **kwargs):

def _prepare_context(self, job):
# pylint: disable=context-overridden
job_model = job.job_model.with_context({})
job_model = job.env["queue.job"].with_context({})
field_records = job_model._fields["records"]
# Filter the context to simulate store/load of the job
job.recordset = field_records.convert_to_write(job.recordset, job_model)
Expand Down
2 changes: 2 additions & 0 deletions queue_job/tests/test_model_job_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ def test_function_job_config(self):
' "func_name": "related_action_foo",'
' "kwargs": {"b": 1}}'
),
"allow_commit": True,
}
)
self.assertEqual(
Expand All @@ -53,5 +54,6 @@ def test_function_job_config(self):
related_action_func_name="related_action_foo",
related_action_kwargs={"b": 1},
job_function_id=job_function.id,
allow_commit=True,
),
)
2 changes: 2 additions & 0 deletions queue_job/views/queue_job_function_views.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<field name="model_id" required="1" />
<field name="method" required="1" />
<field name="channel_id" />
<field name="allow_commit" />
<field name="edit_retry_pattern" widget="ace" />
<field name="edit_related_action" widget="ace" />
</group>
Expand All @@ -24,6 +25,7 @@
<list>
<field name="name" />
<field name="channel_id" />
<field name="allow_commit" />
</list>
</field>
</record>
Expand Down