Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
072b82c
[IMP] queue_job: add pause option on channels
guewen Aug 14, 2026
54e83d8
[FIX] queue_job: validate JobSerialized base_type again
HoloborodkoBohdan Sep 15, 2026
23655b5
[FIX] queue_job: notify managers holding the group through implication
HoloborodkoBohdan Sep 15, 2026
ffacd6f
[BOT] post-merge updates
OCA-git-bot Oct 5, 2026
f26e3d3
[FIX] queue_job: deadlock when the on fail hook writes the job's records
ivantodorovich Sep 29, 2026
f439144
[BOT] post-merge updates
OCA-git-bot Oct 5, 2026
51c8365
[FIX] queue_job: don't start the jobrunner in odoo shell
GuillemCForgeFlow Oct 6, 2026
aac202e
[BOT] post-merge updates
OCA-git-bot Oct 8, 2026
6b3c436
[FIX] queue_job: wake the job runner up on stop
HoloborodkoBohdan Oct 15, 2026
74e0ff9
[IMP] queue_job: clean old jobs from the base autovacuum
ivantodorovich Oct 20, 2026
45aeffe
[UPD] Update queue_job.pot
Oct 26, 2026
67d1fd8
[BOT] post-merge updates
OCA-git-bot Oct 26, 2026
d955299
Update translation files
weblate Oct 26, 2026
1a477a7
[BOT] post-merge updates
OCA-git-bot Oct 26, 2026
80668d1
[BOT] post-merge updates
OCA-git-bot Oct 26, 2026
ba5a2e6
[BOT] post-merge updates
OCA-git-bot Oct 26, 2026
57bb577
[FIX] queue_job: cancel all dependent jobs of a cancelled job
ivantodorovich Oct 20, 2026
a8097d7
[UPD] Update queue_job.pot
Oct 26, 2026
4910cc6
[BOT] post-merge updates
OCA-git-bot Oct 26, 2026
2689973
Update translation files
weblate Oct 26, 2026
40f792c
[IMP] queue_job: pre-commit auto fixes
dhongu Oct 27, 2026
bdff882
[MIG] queue_job: Migration to 20.0
dhongu Oct 27, 2026
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
7 changes: 7 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
exclude: |
(?x)
# NOT INSTALLABLE ADDONS
^base_import_async/|
^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
^setup/|/static/description/index\.html$|
Expand Down
12 changes: 6 additions & 6 deletions 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:aee74431fafa74d2abc078c3686e4d9c6390bacc001cac7c4afa01b9db77ca06
!! source digest: sha256:07592ea84e63ed35de86f099ccb855d656184ecd4a570168b8eed73aab133157
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Mature-brightgreen.png
Expand All @@ -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/19.0/queue_job
:target: https://github.com/OCA/queue/tree/20.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-19-0/queue-19-0-queue_job
:target: https://translation.odoo-community.org/projects/queue-20-0/queue-20-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=19.0
:target: https://runboat.odoo-community.org/builds?repo=OCA/queue&target_branch=20.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|
Expand Down Expand Up @@ -685,7 +685,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:%2019.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:%2020.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 @@ -747,6 +747,6 @@ Current `maintainers <https://odoo-community.org/page/maintainer-role>`__:

|maintainer-guewen| |maintainer-sbidoul|

This module is part of the `OCA/queue <https://github.com/OCA/queue/tree/19.0/queue_job>`_ project on GitHub.
This module is part of the `OCA/queue <https://github.com/OCA/queue/tree/20.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": "19.0.2.1.3",
"version": "20.0.1.0.0",
"author": "Camptocamp,ACSONE SA/NV,Odoo Community Association (OCA)",
"website": "https://github.com/OCA/queue",
"license": "LGPL-3",
Expand All @@ -11,7 +11,7 @@
"external_dependencies": {"python": ["requests", "openupgradelib"]},
"data": [
"security/security.xml",
"security/ir.model.access.csv",
"security/ir.access.csv",
"views/queue_job_views.xml",
"views/queue_job_channel_views.xml",
"views/queue_job_function_views.xml",
Expand All @@ -27,7 +27,7 @@
"queue_job/static/src/views/**/*",
],
},
"installable": False,
"installable": True,
"development_status": "Mature",
"maintainers": ["guewen", "sbidoul"],
"post_init_hook": "post_init_hook",
Expand Down
27 changes: 15 additions & 12 deletions queue_job/controllers/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from werkzeug.exceptions import BadRequest, Forbidden

from odoo import SUPERUSER_ID, api, http
from odoo.service.model import PG_CONCURRENCY_ERRORS_TO_RETRY
from odoo.sql_db import PG_CONCURRENCY_EXCEPTIONS_TO_RETRY
from odoo.tools import config

from ..delay import chain, group
Expand Down Expand Up @@ -98,10 +98,14 @@ def _try_perform_job(cls, env, job):
# TODO refactor, the relation between env and job.env is not clear
assert env.cr is job.env.cr
with _prevent_commit(env.cr):
job.perform()
# Triggers any stored computed fields before calling 'set_done'
# so that will be part of the 'exec_time'
env.flush_all()
# On failure, rolling back the savepoint releases the row locks
# the job took on the records it updated: the failure is handled
# from another cursor, which may write on the same records (e.g.
# the on fail hook).
# On success, leaving the savepoint flushes, before 'set_done', so
# that the stored computed fields are part of the 'exec_time'.
with env.cr.savepoint():
job.perform()
job.set_done()
job.store()
env.flush_all()
Expand All @@ -123,7 +127,7 @@ def _enqueue_dependent_jobs(cls, env, job):
except OperationalError as err:
# Automatically retry the typical transaction serialization
# errors
if err.pgcode not in PG_CONCURRENCY_ERRORS_TO_RETRY:
if not isinstance(err, PG_CONCURRENCY_EXCEPTIONS_TO_RETRY):
raise
if tries >= DEPENDS_MAX_TRIES_ON_CONCURRENCY_FAILURE:
_logger.error(
Expand All @@ -148,7 +152,7 @@ def _enqueue_dependent_jobs(cls, env, job):
@classmethod
def _runjob(cls, env: api.Environment, job: Job) -> None:
def retry_postpone(job, message, seconds=None):
job.env.clear()
job.env.transaction.clear()
with job.in_temporary_env():
job.postpone(result=message, seconds=seconds)
job.set_pending(reset_retry=False)
Expand All @@ -160,7 +164,7 @@ def retry_postpone(job, message, seconds=None):
except OperationalError as err:
# Automatically retry the typical transaction serialization
# errors
if err.pgcode not in PG_CONCURRENCY_ERRORS_TO_RETRY:
if not isinstance(err, PG_CONCURRENCY_EXCEPTIONS_TO_RETRY):
raise

_logger.debug("%s OperationalError, postponed", job)
Expand All @@ -181,7 +185,7 @@ def retry_postpone(job, message, seconds=None):
traceback.print_exc(file=buff)
traceback_txt = buff.getvalue()
_logger.error(traceback_txt)
job.env.clear()
job.env.transaction.clear()
with job.in_temporary_env():
vals = cls._get_failure_values(job, traceback_txt, orig_exception)
job.set_failed(**vals)
Expand Down Expand Up @@ -388,6 +392,5 @@ def _create_graph_test_jobs(

root_delayable.delay()

return (
f"graph uuid: {list(root_delayable._head())[0]._generated_job.graph_uuid}"
)
head = next(iter(root_delayable._head()))
return f"graph uuid: {head._generated_job.graph_uuid}"
14 changes: 2 additions & 12 deletions queue_job/data/queue_data.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<data noupdate="1">
<!-- Queue-job-related subtypes for messaging / Chatter -->
Expand All @@ -7,19 +7,9 @@
<field name="res_model">queue.job</field>
<field name="default" eval="True" />
</record>
<record id="ir_cron_autovacuum_queue_jobs" model="ir.cron">
<field name="name">AutoVacuum Job Queue</field>
<field ref="model_queue_job" name="model_id" />
<field eval="True" name="active" />
<field name="user_id" ref="base.user_root" />
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="state">code</field>
<field name="code">model.autovacuum()</field>
</record>
</data>
<data noupdate="0">
<record model="queue.job.channel" id="channel_root">
<record id="channel_root" model="queue.job.channel">
<field name="name">root</field>
</record>
</data>
Expand Down
1 change: 1 addition & 0 deletions queue_job/data/queue_job_function_data.xml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo noupdate="1">
<record id="job_function_queue_job__test_job" model="queue.job.function">
<field name="model_id" ref="queue_job.model_queue_job" />
Expand Down
6 changes: 3 additions & 3 deletions queue_job/delay.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class Graph:
instances, although ultimately it is used for this purpose.
"""

__slots__ = "_graph"
__slots__ = ("_graph",)

def __init__(self, graph=None):
if graph:
Expand Down Expand Up @@ -314,7 +314,7 @@ class DelayableChain:
delayable/chain/group object of the graph.
"""

__slots__ = ("_graph", "__head", "__tail")
__slots__ = ("__head", "__tail", "_graph")

def __init__(self, *delayables):
self._graph = DelayableGraph()
Expand Down Expand Up @@ -371,7 +371,7 @@ class DelayableGroup:
delayable/chain/group object of the graph.
"""

__slots__ = ("_graph", "_delayables")
__slots__ = ("_delayables", "_graph")

def __init__(self, *delayables):
self._graph = DelayableGraph()
Expand Down
6 changes: 3 additions & 3 deletions queue_job/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class JobSerialized(fields.Json):
_base_type = None

# these are the default values when we convert an empty value
_default_json_mapping = {
_default_json_mapping = { # noqa: RUF012
dict: "{}",
list: "[]",
tuple: "[]",
Expand All @@ -42,8 +42,8 @@ class JobSerialized(fields.Json):
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)
def _setup_attrs__(self, model_class, name): # pylint: disable=missing-return
super()._setup_attrs__(model_class, name)
if self._base_type not in self._default_json_mapping:
msg = f"{self._base_type} is not a supported base type"
raise ValueError(msg)
Expand Down
34 changes: 29 additions & 5 deletions queue_job/i18n/de.po
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,6 @@ msgstr "Argumente"
msgid "Attachment Count"
msgstr "Anzahl der Anhänge"

#. module: queue_job
#: model:ir.actions.server,name:queue_job.ir_cron_autovacuum_queue_jobs_ir_actions_server
msgid "AutoVacuum Job Queue"
msgstr "AutoVacuum für Job-Warteschlange"

#. module: queue_job
#: model:ir.model,name:queue_job.model_base
msgid "Base"
Expand Down Expand Up @@ -117,6 +112,12 @@ msgstr ""
msgid "Cancelled"
msgstr ""

#. module: queue_job
#. odoo-python
#: code:addons/queue_job/job.py:0
msgid "Cancelled because a job it depends on was cancelled"
msgstr ""

#. module: queue_job
#. odoo-python
#: code:addons/queue_job/models/queue_job.py:0
Expand Down Expand Up @@ -231,6 +232,16 @@ msgstr ""
msgid "Dependency Graph"
msgstr ""

#. module: queue_job
#: model:ir.model.fields,field_description:queue_job.field_queue_job__dependency_ids
msgid "Dependency Jobs"
msgstr ""

#. module: queue_job
#: model:ir.model.fields,field_description:queue_job.field_queue_job__dependent_ids
msgid "Dependent Jobs"
msgstr ""

#. module: queue_job
#: model:ir.model.fields,field_description:queue_job.field_queue_job__name
msgid "Description"
Expand Down Expand Up @@ -469,12 +480,22 @@ msgstr "Job ist fehlgeschlagen"
msgid "Jobs"
msgstr "Jobs"

#. module: queue_job
#: model:ir.model.fields,help:queue_job.field_queue_job__dependent_ids
msgid "Jobs depending on this job."
msgstr ""

#. module: queue_job
#. odoo-python
#: code:addons/queue_job/models/queue_job.py:0
msgid "Jobs for graph %s"
msgstr ""

#. module: queue_job
#: model:ir.model.fields,help:queue_job.field_queue_job__dependency_ids
msgid "Jobs this job depends on."
msgstr ""

#. module: queue_job
#: model:ir.model.fields,field_description:queue_job.field_queue_job__kwargs
msgid "Kwargs"
Expand Down Expand Up @@ -945,6 +966,9 @@ msgstr ""
msgid "id"
msgstr ""

#~ msgid "AutoVacuum Job Queue"
#~ msgstr "AutoVacuum für Job-Warteschlange"

#~ msgid "Group By"
#~ msgstr "Gruppieren nach"

Expand Down
34 changes: 29 additions & 5 deletions queue_job/i18n/es.po
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,6 @@ msgstr "Argumentos"
msgid "Attachment Count"
msgstr "Nº de archivos adjuntos"

#. module: queue_job
#: model:ir.actions.server,name:queue_job.ir_cron_autovacuum_queue_jobs_ir_actions_server
msgid "AutoVacuum Job Queue"
msgstr "Vaciado automático de la cola de trabajos"

#. module: queue_job
#: model:ir.model,name:queue_job.model_base
msgid "Base"
Expand Down Expand Up @@ -120,6 +115,12 @@ msgstr "Cancelar trabajos"
msgid "Cancelled"
msgstr "Cancelada"

#. module: queue_job
#. odoo-python
#: code:addons/queue_job/job.py:0
msgid "Cancelled because a job it depends on was cancelled"
msgstr ""

#. module: queue_job
#. odoo-python
#: code:addons/queue_job/models/queue_job.py:0
Expand Down Expand Up @@ -234,6 +235,16 @@ msgstr "Dependencias"
msgid "Dependency Graph"
msgstr "Gráfico de dependencias"

#. module: queue_job
#: model:ir.model.fields,field_description:queue_job.field_queue_job__dependency_ids
msgid "Dependency Jobs"
msgstr ""

#. module: queue_job
#: model:ir.model.fields,field_description:queue_job.field_queue_job__dependent_ids
msgid "Dependent Jobs"
msgstr ""

#. module: queue_job
#: model:ir.model.fields,field_description:queue_job.field_queue_job__name
msgid "Description"
Expand Down Expand Up @@ -470,12 +481,22 @@ msgstr "Trabajo fallido"
msgid "Jobs"
msgstr "Trabajos"

#. module: queue_job
#: model:ir.model.fields,help:queue_job.field_queue_job__dependent_ids
msgid "Jobs depending on this job."
msgstr ""

#. module: queue_job
#. odoo-python
#: code:addons/queue_job/models/queue_job.py:0
msgid "Jobs for graph %s"
msgstr "Trabajos para gráfico %s"

#. module: queue_job
#: model:ir.model.fields,help:queue_job.field_queue_job__dependency_ids
msgid "Jobs this job depends on."
msgstr ""

#. module: queue_job
#: model:ir.model.fields,field_description:queue_job.field_queue_job__kwargs
msgid "Kwargs"
Expand Down Expand Up @@ -957,6 +978,9 @@ msgstr "Pid del trabajador"
msgid "id"
msgstr ""

#~ msgid "AutoVacuum Job Queue"
#~ msgstr "Vaciado automático de la cola de trabajos"

#~ msgid "Group By"
#~ msgstr "Agrupar por"

Expand Down
Loading
Loading