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 @@ -23,13 +23,13 @@ Available addons
addon | version | maintainers | summary
--- | --- | --- | ---
[base_import_async](base_import_async/) | 18.0.1.0.0 | | Import CSV files in the background
[queue_job](queue_job/) | 18.0.4.1.0 | <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/) | 18.0.4.1.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/) | 18.0.1.1.1 | | Job Queue Batch
[queue_job_cron](queue_job_cron/) | 18.0.1.1.1 | | Scheduled Actions as Queue Jobs
[queue_job_cron_jobrunner](queue_job_cron_jobrunner/) | 18.0.1.0.1 | <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_profiler](queue_job_profiler/) | 18.0.1.0.1 | <a href='https://github.com/simahawk'><img src='https://github.com/simahawk.png' width='32' height='32' style='border-radius:50%;' alt='simahawk'/></a> | Job Queue Profiler
[queue_job_subscribe](queue_job_subscribe/) | 18.0.1.0.0 | | Control which users are subscribed to queue job notifications
[test_queue_job](test_queue_job/) | 18.0.2.1.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/) | 18.0.2.1.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/) | 18.0.1.0.0 | | Test Job Queue Batch

[//]: # (end addons)
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:338aa143588050eeb76e4d0a2a40e8a35bfa0263e7c4cba00bfb2d5491696dd5
!! source digest: sha256:9f83bd687b03da26cd04609397b95315e179cdc7781390f574ef7b2a77061fec
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |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": "18.0.4.1.0",
"version": "18.0.4.1.2",
"author": "Camptocamp,ACSONE SA/NV,Odoo Community Association (OCA)",
"website": "https://github.com/OCA/queue",
"license": "LGPL-3",
Expand Down
15 changes: 11 additions & 4 deletions queue_job/delay.py
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,7 @@ class Delayable:
"recordset",
"_graph",
"_job_method",
"_job_method_name",
"_job_args",
"_job_kwargs",
"_generated_job",
Expand Down Expand Up @@ -471,6 +472,7 @@ def __init__(
self.identity_key = identity_key

self._job_method = None
self._job_method_name = ""
self._job_args = ()
self._job_kwargs = {}

Expand All @@ -484,8 +486,7 @@ def _tail(self):

def __repr__(self):
return (
f"Delayable({self.recordset}."
f"{self._job_method.__name__ if self._job_method else ''}"
f"Delayable({self.recordset}.{self._job_method_name}"
f"({self._job_args}, {self._job_kwargs}))"
)

Expand Down Expand Up @@ -548,7 +549,8 @@ def split(self, size, chain=False):
identity_key=self.identity_key,
)
# Update the __self__
delayable._job_method = getattr(recordset, self._job_method.__name__)
delayable._job_method = getattr(recordset, self._job_method_name)
delayable._job_method_name = self._job_method_name
delayable._job_args = self._job_args
delayable._job_kwargs = self._job_kwargs

Expand All @@ -557,7 +559,7 @@ def split(self, size, chain=False):
description = self.description or (
self._job_method.__doc__.splitlines()[0].strip()
if self._job_method.__doc__
else f"{self.recordset._name}.{self._job_method.__name__}"
else f"{self.recordset._name}.{self._job_method_name}"
)
for index, delayable in enumerate(delayables):
delayable.set(
Expand All @@ -574,6 +576,7 @@ def _build_job(self):
return self._generated_job
self._generated_job = Job(
self._job_method,
method_name=self._job_method_name,
args=self._job_args,
kwargs=self._job_kwargs,
priority=self.priority,
Expand All @@ -599,6 +602,10 @@ def __getattr__(self, name):
)
recordset_method = getattr(self.recordset, name)
self._job_method = recordset_method
# Keep the name that was looked up: the method found under it may
# carry another __name__ (e.g. replaced by auditlog), and the job must
# resolve the same attribute again when it is loaded and run.
self._job_method_name = name
return self._store_args

def _execute_direct(self):
Expand Down
9 changes: 7 additions & 2 deletions queue_job/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ def _load_from_db_record(cls, job_db_record):

job_ = cls(
method,
method_name=method_name,
args=args,
kwargs=kwargs,
priority=stored.priority,
Expand Down Expand Up @@ -385,6 +386,7 @@ def __init__(
description=None,
channel=None,
identity_key=None,
method_name=None,
):
"""Create a Job

Expand All @@ -409,6 +411,9 @@ def __init__(
:param identity_key: A hash to uniquely identify a job, or a function
that returns this hash (the function takes the job
as argument)
:param method_name: name of the method on the recordset. Defaults to
``func.__name__``; pass it when the method was
looked up under a different name than its own.
"""
if args is None:
args = ()
Expand All @@ -424,7 +429,7 @@ def __init__(
raise TypeError("Job accepts only methods of Models")

recordset = func.__self__
self.method_name = func.__name__
self.method_name = method_name or func.__name__
self.recordset = recordset

self.job_config = (
Expand Down Expand Up @@ -781,7 +786,7 @@ def description(self):
elif self.func.__doc__:
return self.func.__doc__.splitlines()[0].strip()
else:
return f"{self.model_name}.{self.func.__name__}"
return f"{self.model_name}.{self.method_name}"

@property
def uuid(self):
Expand Down
3 changes: 2 additions & 1 deletion queue_job/jobrunner/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@ def prefork_worker_pop(server, pid):

def threaded_start(server, *args, **kwargs):
res = orig_threaded_start(server, *args, **kwargs)
_start_runner_thread("threaded server")
if not kwargs.get("stop"):
_start_runner_thread("threaded server")
return res


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:338aa143588050eeb76e4d0a2a40e8a35bfa0263e7c4cba00bfb2d5491696dd5
!! source digest: sha256:9f83bd687b03da26cd04609397b95315e179cdc7781390f574ef7b2a77061fec
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<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/18.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-18-0/queue-18-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=18.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": "18.0.2.1.0",
"version": "18.0.2.1.1",
"author": "Camptocamp,Odoo Community Association (OCA)",
"license": "LGPL-3",
"category": "Generic Modules",
Expand Down
36 changes: 36 additions & 0 deletions test_queue_job/tests/test_delayable.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
chain,
group,
)
from odoo.addons.queue_job.job import Job


class TestDelayable(common.TransactionCase):
Expand Down Expand Up @@ -308,3 +309,38 @@ def test_delay_job_already_exists(self):
node.on_done(node2).delay()
self.assert_generated_job(node, node2)
self.assert_dependencies({node: {}, node2: {node}})

def _replace_testing_method_under_another_name(self):
"""Put a function named ``testing_method_renamed`` into the
``testing_method`` slot, the way auditlog replaces write and unlink."""
cls = type(self.test_model)
original = cls.testing_method

def testing_method_renamed(self, *args, **kwargs):
return original(self, *args, **kwargs)

self.patch(cls, "testing_method", testing_method_renamed)

def test_delayable_keeps_requested_method_name(self):
self._replace_testing_method_under_another_name()
node = Delayable(self.test_model).testing_method(1)
node.delay()
job = node._generated_job
self.assertEqual(job.method_name, "testing_method")
self.assertEqual(job.db_record().method_name, "testing_method")
# Loading the job resolves the same name again
loaded = Job.load(self.env, job.uuid)
self.assertEqual(loaded.method_name, "testing_method")

def test_with_delay_keeps_requested_method_name(self):
self._replace_testing_method_under_another_name()
job = self.test_model.with_delay().testing_method(1)
self.assertEqual(job.method_name, "testing_method")

def test_delayable_split_keeps_requested_method_name(self):
self._replace_testing_method_under_another_name()
records = self.test_model.create([{"name": "a"}, {"name": "b"}])
group = Delayable(records).testing_method(1).split(1)
group.delay()
for node in group._delayables:
self.assertEqual(node._generated_job.method_name, "testing_method")
Loading