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
2 changes: 0 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ exclude: |
(?x)
# NOT INSTALLABLE ADDONS
^base_import_async/|
^queue_job/|
^queue_job_batch/|
^queue_job_cron/|
^queue_job_cron_jobrunner/|
^queue_job_subscribe/|
^test_queue_job/|
^test_queue_job_batch/|
# END NOT INSTALLABLE ADDONS
# Files and folders generated by bots, to avoid loops
Expand Down
3 changes: 1 addition & 2 deletions base_import_async/models/base_import_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,7 @@ def _split_file(
description = _(
"Import %(model)s from file %(file_name)s - "
"#%(chunk)s - lines %(from)s to %(to)s"
)
description = description % {
) % {
"model": translated_model_name,
"file_name": file_name,
"chunk": chunk,
Expand Down
10 changes: 5 additions & 5 deletions queue_job/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ Job Queue
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html
:alt: License: LGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fqueue-lightgray.png?logo=github
:target: https://github.com/OCA/queue/tree/18.0/queue_job
:target: https://github.com/OCA/queue/tree/19.0/queue_job
:alt: OCA/queue
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/queue-18-0/queue-18-0-queue_job
:target: https://translation.odoo-community.org/projects/queue-19-0/queue-19-0-queue_job
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/queue&target_branch=18.0
:target: https://runboat.odoo-community.org/builds?repo=OCA/queue&target_branch=19.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|
Expand Down Expand Up @@ -661,7 +661,7 @@ Bug Tracker
Bugs are tracked on `GitHub Issues <https://github.com/OCA/queue/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/queue/issues/new?body=module:%20queue_job%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
`feedback <https://github.com/OCA/queue/issues/new?body=module:%20queue_job%0Aversion:%2019.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Expand Down Expand Up @@ -720,6 +720,6 @@ Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:

|maintainer-guewen|

This module is part of the `OCA/queue <https://github.com/OCA/queue/tree/18.0/queue_job>`_ project on GitHub.
This module is part of the `OCA/queue <https://github.com/OCA/queue/tree/19.0/queue_job>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
6 changes: 3 additions & 3 deletions 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.2.0.2",
"version": "19.0.1.0.0",
"author": "Camptocamp,ACSONE SA/NV,Odoo Community Association (OCA)",
"website": "https://github.com/OCA/queue",
"license": "LGPL-3",
Expand All @@ -24,10 +24,10 @@
],
"assets": {
"web.assets_backend": [
"/queue_job/static/src/views/**/*",
"queue_job/static/src/views/**/*",
],
},
"installable": False,
"installable": True,
"development_status": "Mature",
"maintainers": ["guewen"],
"post_init_hook": "post_init_hook",
Expand Down
6 changes: 3 additions & 3 deletions queue_job/controllers/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from psycopg2 import OperationalError, errorcodes
from werkzeug.exceptions import BadRequest, Forbidden

from odoo import SUPERUSER_ID, _, api, http
from odoo import SUPERUSER_ID, api, http
from odoo.modules.registry import Registry
from odoo.service.model import PG_CONCURRENCY_ERRORS_TO_RETRY

Expand Down Expand Up @@ -179,7 +179,7 @@ def create_test_job(
failure_rate=0,
):
if not http.request.env.user.has_group("base.group_erp_manager"):
raise Forbidden(_("Access Denied"))
raise Forbidden(http.request.env._("Access Denied"))

if failure_rate is not None:
try:
Expand Down Expand Up @@ -280,7 +280,7 @@ def _create_graph_test_jobs(
priority=priority,
max_retries=max_retries,
channel=channel,
description="%s #%d" % (description, current_count),
description=f"{description} #{current_count}",
)._test_job(failure_rate=failure_rate)
)

Expand Down
3 changes: 2 additions & 1 deletion queue_job/delay.py
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,8 @@ def __del__(self):
def _set_from_dict(self, properties):
for key, value in properties.items():
if key not in self._properties:
raise ValueError(f"No property {key}")
msg = f"No property {key}"
raise ValueError(msg)
setattr(self, key, value)

def set(self, *args, **kwargs):
Expand Down
6 changes: 4 additions & 2 deletions queue_job/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from odoo import fields, models
from odoo.tools.func import lazy
from odoo.tools.misc import SENTINEL


class JobSerialized(fields.Json):
Expand Down Expand Up @@ -38,13 +39,14 @@ class JobSerialized(fields.Json):
),
}

def __init__(self, string=fields.SENTINEL, base_type=fields.SENTINEL, **kwargs):
def __init__(self, string=SENTINEL, base_type=SENTINEL, **kwargs):
super().__init__(string=string, _base_type=base_type, **kwargs)

def _setup_attrs(self, model, name): # pylint: disable=missing-return
super()._setup_attrs(model, name)
if self._base_type not in self._default_json_mapping:
raise ValueError(f"{self._base_type} is not a supported base type")
msg = f"{self._base_type} is not a supported base type"
raise ValueError(msg)

def _base_type_default_json(self, env):
default_json = self._default_json_mapping.get(self._base_type)
Expand Down
12 changes: 6 additions & 6 deletions queue_job/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,8 @@ def load(cls, env, job_uuid):
"""
stored = cls.db_records_from_uuids(env, [job_uuid])
if not stored:
raise NoSuchJobError(f"Job {job_uuid} does no longer exist in the storage.")
msg = f"Job {job_uuid} does no longer exist in the storage."
raise NoSuchJobError(msg)
return cls._load_from_db_record(stored)

@classmethod
Expand Down Expand Up @@ -505,7 +506,7 @@ def perform(self):
# traceback and message:
# http://blog.ianbicking.org/2007/09/12/re-raising-exceptions/
new_exc = FailedJobError(
"Max. retries (%d) reached: %s" % (self.max_retries, value or type_)
f"Max. retries ({self.max_retries}) reached: {value or type_}"
)
raise new_exc from err
raise
Expand Down Expand Up @@ -813,7 +814,7 @@ def set_failed(self, **kw):
setattr(self, k, v)

def __repr__(self):
return "<Job %s, priority:%d>" % (self.uuid, self.priority)
return f"<Job {self.uuid}, priority:{self.priority}>"

def _get_retry_seconds(self, seconds=None):
retry_pattern = self.job_config.retry_pattern
Expand All @@ -828,7 +829,7 @@ def _get_retry_seconds(self, seconds=None):
break
elif not seconds:
seconds = RETRY_INTERVAL
if isinstance(seconds, (list | tuple)):
if isinstance(seconds, list | tuple):
seconds = randint(seconds[0], seconds[1])
return seconds

Expand Down Expand Up @@ -856,8 +857,7 @@ def related_action(self):
funcname = record._default_related_action
if not isinstance(funcname, str):
raise ValueError(
"related_action must be the name of the "
"method on queue.job as string"
"related_action must be the name of the method on queue.job as string"
)
action = getattr(record, funcname)
action_kwargs = self.job_config.related_action_kwargs
Expand Down
14 changes: 12 additions & 2 deletions queue_job/jobrunner/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,32 @@
import logging
from threading import Thread
import time
from configparser import ConfigParser

from odoo.service import server
from odoo.tools import config

try:
# Preferred source when available: structured [queue_job] section provided
# by OCA's server_environment addon.
from odoo.addons.server_environment import serv_config

if serv_config.has_section("queue_job"):
queue_job_config = serv_config["queue_job"]
else:
queue_job_config = {}
except ImportError:
queue_job_config = config.misc.get("queue_job", {})
# No server_environment: try to read a [queue_job] section from odoo.conf
queue_job_config = {}
cfg_path = config.get("config")
if cfg_path:
cp = ConfigParser(interpolation=None)
cp.read(cfg_path)
if cp.has_section("queue_job"):
queue_job_config = dict(cp["queue_job"])


from .runner import QueueJobRunner, _channels
from .runner import QueueJobRunner, _channels # noqa: E402

_logger = logging.getLogger(__name__)

Expand Down
15 changes: 6 additions & 9 deletions queue_job/jobrunner/channels.py
Original file line number Diff line number Diff line change
Expand Up @@ -455,12 +455,9 @@ def get_subchannel_by_name(self, subchannel_name):

def __str__(self):
capacity = "∞" if self.capacity is None else str(self.capacity)
return "%s(C:%s,Q:%d,R:%d,F:%d)" % (
self.fullname,
capacity,
len(self._queue),
len(self._running),
len(self._failed),
return (
f"{self.fullname}(C:{capacity},Q:{len(self._queue)},"
f"R:{len(self._running)},F:{len(self._failed)})"
)

def remove(self, job):
Expand Down Expand Up @@ -894,8 +891,7 @@ def parse_simple_config(cls, config_string):
)
if k in config:
raise ValueError(
f"Invalid channel config {config_string}: "
f"duplicate key {k}"
f"Invalid channel config {config_string}: duplicate key {k}"
)
config[k] = v
else:
Expand Down Expand Up @@ -996,7 +992,8 @@ def get_channel_by_name(
if channel_name in self._channels_by_name:
return self._channels_by_name[channel_name]
if not autocreate and not parent_fallback:
raise ChannelNotFound(f"Channel {channel_name} not found")
msg = f"Channel {channel_name} not found"
raise ChannelNotFound(msg)
parent = self._root_channel
if parent_fallback:
# Look for first direct parent w/ config.
Expand Down
9 changes: 4 additions & 5 deletions queue_job/jobrunner/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -472,11 +472,10 @@ def from_environ_or_config(cls):
return runner

def get_db_names(self):
if config["db_name"]:
db_names = config["db_name"].split(",")
else:
db_names = odoo.service.db.list_dbs(True)
return db_names
db_names = config["db_name"]
if db_names:
return db_names
return odoo.service.db.list_dbs(True)

def close_databases(self, remove_jobs=True):
for db_name, db in self.db_by_name.items():
Expand Down
26 changes: 13 additions & 13 deletions queue_job/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,9 +193,17 @@ def foo_job_options(self, arg1):
}

def _register_hook(self):
self._patch_method(
# patch the method at registry time
patched = self._patch_job_auto_delay(
"foo", context_key="auto_delay_foo"
)
setattr(
type(self),
"foo",
self._patch_job_auto_delay("foo", context_key="auto_delay_foo")
functools.update_wrapper(
patched,
getattr(type(self), "foo"),
),
)
return super()._register_hook()

Expand Down Expand Up @@ -224,8 +232,9 @@ def auto_delay_wrapper(self, *args, **kwargs):
delayed = self.with_delay(**job_options)
return getattr(delayed, method_name)(*args, **kwargs)

origin = getattr(self, method_name)
return functools.update_wrapper(auto_delay_wrapper, origin)
origin_func = getattr(type(self), method_name)
auto_delay_wrapper.origin = origin_func
return functools.update_wrapper(auto_delay_wrapper, origin_func)

@api.model
def _job_store_values(self, job):
Expand Down Expand Up @@ -259,12 +268,3 @@ def _job_prepare_context_before_enqueue(self):
for key, value in self.env.context.items()
if key in self._job_prepare_context_before_enqueue_keys()
}

@classmethod
def _patch_method(cls, name, method):
origin = getattr(cls, name)
method.origin = origin
# propagate decorators from origin to method, and apply api decorator
wrapped = api.propagate(origin, method)
wrapped.origin = origin
setattr(cls, name, wrapped)
Loading