Skip to content
Merged
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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ addon | version | maintainers | summary
--- | --- | --- | ---
[base_export_async](base_export_async/) | 16.0.1.2.0 | | Asynchronous export with job queue
[base_import_async](base_import_async/) | 16.0.1.2.1 | | Import CSV files in the background
[queue_job](queue_job/) | 16.0.3.0.1 | <a href='https://github.com/guewen'><img src='https://github.com/guewen.png' width='32' height='32' style='border-radius:50%;' alt='guewen'/></a> <a href='https://github.com/sbidoul'><img src='https://github.com/sbidoul.png' width='32' height='32' style='border-radius:50%;' alt='sbidoul'/></a> | Job Queue
[queue_job](queue_job/) | 16.0.3.0.2 | <a href='https://github.com/guewen'><img src='https://github.com/guewen.png' width='32' height='32' style='border-radius:50%;' alt='guewen'/></a> <a href='https://github.com/sbidoul'><img src='https://github.com/sbidoul.png' width='32' height='32' style='border-radius:50%;' alt='sbidoul'/></a> | Job Queue
[queue_job_batch](queue_job_batch/) | 16.0.1.0.1 | | Job Queue Batch
[queue_job_cron](queue_job_cron/) | 16.0.2.1.0 | | Scheduled Actions as Queue Jobs
[queue_job_cron_jobrunner](queue_job_cron_jobrunner/) | 16.0.1.1.0 | <a href='https://github.com/ivantodorovich'><img src='https://github.com/ivantodorovich.png' width='32' height='32' style='border-radius:50%;' alt='ivantodorovich'/></a> | Run jobs without a dedicated JobRunner
[queue_job_subscribe](queue_job_subscribe/) | 16.0.1.1.0 | | Control which users are subscribed to queue job notifications
[queue_job_web_notify](queue_job_web_notify/) | 16.0.1.0.0 | | This module allows to display a notification to the related user of a failed job. It uses the web_notify notification feature.
[test_queue_job](test_queue_job/) | 16.0.2.5.0 | <a href='https://github.com/sbidoul'><img src='https://github.com/sbidoul.png' width='32' height='32' style='border-radius:50%;' alt='sbidoul'/></a> | Queue Job Tests
[test_queue_job](test_queue_job/) | 16.0.2.5.1 | <a href='https://github.com/sbidoul'><img src='https://github.com/sbidoul.png' width='32' height='32' style='border-radius:50%;' alt='sbidoul'/></a> | Queue Job Tests
[test_queue_job_batch](test_queue_job_batch/) | 16.0.1.0.0 | | Test Job Queue Batch


Expand Down
2 changes: 1 addition & 1 deletion queue_job/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Job Queue
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:078ff84f658e3a8953ba800728b7b57d5effbaa0083ff7ab9c1b8134b77bb885
!! source digest: sha256:7387273e60279f8c69c8b3052a07d6fed49d33f14949cbfd7a41f41852ccbb4d
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Mature-brightgreen.png
Expand Down
2 changes: 1 addition & 1 deletion queue_job/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

{
"name": "Job Queue",
"version": "16.0.3.0.1",
"version": "16.0.3.0.2",
"author": "Camptocamp,ACSONE SA/NV,Odoo Community Association (OCA)",
"website": "https://github.com/OCA/queue",
"license": "LGPL-3",
Expand Down
41 changes: 40 additions & 1 deletion queue_job/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,30 @@
from random import randint

import odoo
from odoo.models import BaseModel

from .exception import FailedJobError, NoSuchJobError, RetryableJobError


def _rebind_to_cr(value, cr):
"""Rebind any BaseModel inside ``value`` to the cursor ``cr``.

Recurses into lists, tuples and dicts. Preserves uid/su/context of each
inner env - only the cursor is swapped. Recordsets already bound to
``cr`` and non-recordset values pass through untouched. Containers are
rebuilt, so in-place changes to the result are lost.
"""
if isinstance(value, BaseModel):
if value.env.cr is cr:
return value
return value.with_env(value.env(cr=cr))
if isinstance(value, (list, tuple)):
return type(value)(_rebind_to_cr(v, cr) for v in value)
if isinstance(value, dict):
return {k: _rebind_to_cr(v, cr) for k, v in value.items()}
return value


WAIT_DEPENDENCIES = "wait_dependencies"
PENDING = "pending"
ENQUEUED = "enqueued"
Expand Down Expand Up @@ -533,8 +554,8 @@ def perform(self):
def in_temporary_env(self):
with self.env.registry.cursor() as new_cr:
env = self.env
self._env = env(cr=new_cr)
try:
self._env = env(cr=new_cr)
yield
finally:
self._env = env
Expand Down Expand Up @@ -705,6 +726,24 @@ def env(self):
def _env(self, env):
self.recordset = self.recordset.with_env(env)

@property
def args(self):
"""Positional arguments, rebound to the job's current cursor."""
return _rebind_to_cr(self._args, self.env.cr)

@args.setter
def args(self, value):
self._args = value

@property
def kwargs(self):
"""Keyword arguments, rebound to the job's current cursor."""
return _rebind_to_cr(self._kwargs, self.env.cr)

@kwargs.setter
def kwargs(self, value):
self._kwargs = value

@property
def func(self):
recordset = self.recordset.with_context(job_uuid=self.uuid)
Expand Down
2 changes: 1 addition & 1 deletion queue_job/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ <h1>Job Queue</h1>
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:078ff84f658e3a8953ba800728b7b57d5effbaa0083ff7ab9c1b8134b77bb885
!! source digest: sha256:7387273e60279f8c69c8b3052a07d6fed49d33f14949cbfd7a41f41852ccbb4d
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Mature" src="https://img.shields.io/badge/maturity-Mature-brightgreen.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/lgpl-3.0-standalone.html"><img alt="License: LGPL-3" src="https://img.shields.io/badge/license-LGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/queue/tree/16.0/queue_job"><img alt="OCA/queue" src="https://img.shields.io/badge/github-OCA%2Fqueue-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/queue-16-0/queue-16-0-queue_job"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/queue&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>This addon adds an integrated Job Queue to Odoo.</p>
Expand Down
2 changes: 1 addition & 1 deletion test_queue_job/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

{
"name": "Queue Job Tests",
"version": "16.0.2.5.0",
"version": "16.0.2.5.1",
"author": "Camptocamp,Odoo Community Association (OCA)",
"license": "LGPL-3",
"category": "Generic Modules",
Expand Down
8 changes: 8 additions & 0 deletions test_queue_job/data/queue_job_function_data.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@
<field name="method">job_with_retry_pattern__no_zero</field>
<field name="retry_pattern" eval="{3: 180}" />
</record>
<record
id="job_function_test_queue_job_job_commit_with_arg_records"
model="queue.job.function"
>
<field name="model_id" ref="test_queue_job.model_test_queue_job" />
<field name="method">job_commit_with_arg_records</field>
<field name="allow_commit" eval="True" />
</record>
<record
id="job_function_test_queue_channel_job_sub_channel"
model="queue.job.function"
Expand Down
13 changes: 13 additions & 0 deletions test_queue_job/models/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,19 @@ def job_alter_mutable(self, mutable_arg, mutable_kwarg=None):
mutable_kwarg["b"] = 2
return mutable_arg, mutable_kwarg

def job_commit_with_arg_records(
self, record, record_list=None, record_dict=None, token=None
):
assert record.env.cr is self.env.cr, "record argument cursor was not rebound"
assert (
not record_list or record_list[0].env.cr is self.env.cr
), "record list argument cursor was not rebound"
assert (
not record_dict or record_dict["record"].env.cr is self.env.cr
), "record dict argument cursor was not rebound"
record.env.cr.commit() # pylint: disable=invalid-commit
return token

def delay_me(self, arg, kwarg=None):
return arg, kwarg

Expand Down
12 changes: 12 additions & 0 deletions test_queue_job/tests/test_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import odoo.tests.common as common

from odoo.addons.queue_job import identity_exact
from odoo.addons.queue_job.controllers.main import RunJobController
from odoo.addons.queue_job.delay import DelayableGraph
from odoo.addons.queue_job.exception import (
FailedJobError,
Expand Down Expand Up @@ -68,6 +69,17 @@ def test_perform_args(self):
result = test_job.perform()
self.assertEqual(result, (("o", "k"), {"c": "!"}))

def test_allow_commit_rebinds_recordsets_in_args(self):
record = self.env.user.partner_id
job = (
self.env["test.queue.job"]
.with_delay()
.job_commit_with_arg_records(record, [record], {"record": record}, "ok")
)
RunJobController._runjob(self.env, job)
self.assertEqual(job.state, DONE)
self.assertEqual(job.result, "ok")

def test_retryable_error(self):
test_job = Job(self.method, kwargs={"raise_retry": True}, max_retries=3)
self.assertEqual(test_job.retry, 0)
Expand Down