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
80 changes: 80 additions & 0 deletions queue_job_pause/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
===================
Queue Job Pause
===================

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-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_pause
: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_pause
: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
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This module inherith of `queue_job` module to add a new feature, allows to change a channel job to a paused channel (capacity equals zero) using a wizard.

**Table of contents**

.. contents::
:local:

Usage
=====

In some cases, we need to pause only a job since that it is used to schedule a process for a future date but is needed to filter only the paused ones.

Allows to change a channel job to a paused channel (capacity equals zero) using a wizard.

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_pause%0Aversion:%2018.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.

Credits
=======

Authors
-------

* Vauxoo

Contributors
------------

- Jonathan Osorio Alcalá <jonathan@vauxoo.com>

Other credits
-------------

This module was created based on this patch: https://github.com/Vauxoo/queue/pull/10

Maintainers
-----------

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

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

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
3 changes: 3 additions & 0 deletions queue_job_pause/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from . import models
from . import wizards
from . import jobrunner
17 changes: 17 additions & 0 deletions queue_job_pause/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html)

{
"name": "Job Queue Pause Channels",
"version": "18.0.1.0.0",
"author": "Camptocamp,ACSONE SA/NV,Odoo Community Association (OCA)",
"website": "https://github.com/OCA/queue",
"license": "LGPL-3",
"category": "Generic Modules",
"depends": ["queue_job"],
"data": [
"security/ir.model.access.csv",
"wizards/queue_jobs_pause_channel_views.xml",
"data/queue_data.xml",
],
"installable": True,
}
7 changes: 7 additions & 0 deletions queue_job_pause/data/queue_data.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record model="queue.job.channel" id="channel_pause">
<field name="name">pause</field>
<field name="parent_id" ref="queue_job.channel_root" />
</record>
</odoo>
17 changes: 17 additions & 0 deletions queue_job_pause/job.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright 2013-2020 Camptocamp
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html)

from ..queue_job.job import Job

PAUSE_CHANNEL = "root.pause"


class JobPause(Job):
def _store_values(self, create=False):
vals = super().arrancar_motor(create)
if self.channel:
vals["channel"] = self.channel
return vals

def change_job_channel(self, to_channel):
self.channel = to_channel
94 changes: 94 additions & 0 deletions queue_job_pause/jobrunner/channels.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Copyright (c) 2015-2016 ACSONE SA/NV (<http://acsone.eu>)
# Copyright 2015-2016 Camptocamp SA
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html)

from odoo import _

from ....queue_job.jobrunner.channels import Channel, ChannelManager, split_strip
from ..job import PAUSE_CHANNEL


class ChannelPause(Channel):
def __str__(self):
default_capacity = "0" if self.name == PAUSE_CHANNEL else "∞"
capacity = default_capacity if not self.capacity 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),
)

def has_capacity(self):
"""This method has been copied entirely from the parent class."""
if self.sequential and self._failed:
# a sequential queue blocks on failed jobs
return False
# MODIFY: the original logic was: `if not self.capacity:`
if not self.capacity and self.fullname != PAUSE_CHANNEL:
# unlimited capacity
return True
return len(self._running) < self.capacity


class ChannelManagerPause(ChannelManager):
@classmethod
def parse_simple_config(cls, config_string):
"""This method has been copied entirely from the parent class."""
res = []
config_string = config_string.replace("\n", ",")
for channel_config_string in split_strip(config_string, ","):
if not channel_config_string:
# ignore empty entries (commented lines, trailing commas)
continue
config = {}
config_items = split_strip(channel_config_string, ":")
name = config_items[0]
if not name:
raise ValueError(
_("Invalid channel config %s: missing channel name", config_string)
)
config["name"] = name
if len(config_items) > 1:
capacity = config_items[1]
try:
config["capacity"] = int(capacity)
# MODIFY: Add the `if` logic.
if name == PAUSE_CHANNEL and config["capacity"] != 0:
raise Exception(
_("Channel 'pause' must be capacity equal to zero")
)
except Exception as ex:
raise ValueError(
_(
f"Invalid channel config {config_string}: "
f"invalid capacity {capacity}"
)
) from ex
for config_item in config_items[2:]:
kv = split_strip(config_item, "=")
if len(kv) == 1:
k, v = kv[0], True
elif len(kv) == 2:
k, v = kv
else:
raise ValueError(
_(
f"Invalid channel config {config_string}: "
f"incorrect config item {config_item}",
)
)
if k in config:
raise ValueError(
_(
f"Invalid channel config {config_string}: "
f"duplicate key {k}",
)
)
config[k] = v
else:
# MODIFY: the original logic was `config["capacity"] = 1`
config["capacity"] = 0 if name == PAUSE_CHANNEL else 1
res.append(config)
return res
1 change: 1 addition & 0 deletions queue_job_pause/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import queue_job
40 changes: 40 additions & 0 deletions queue_job_pause/models/queue_job.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Copyright 2013-2020 Camptocamp SA
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html)

from odoo import exceptions, models

from ..job import PAUSE_CHANNEL, Job


class QueueJob(models.Model):
"""Inherit model storing the jobs to be executed."""

_inherit = "queue.job"

def _change_job_pause_channel(self):
"""Change the state of the `Job` object
Changing the channel of the Job will automatically change some fields
(date, result, ...).
"""
for record in self:
job_ = Job.load(record.env, record.uuid)
to_channel = ""
if record.channel == PAUSE_CHANNEL:
# Get original channel
to_channel = record.job_function_id.channel
record.channel = record.job_function_id.channel
else:
to_channel = PAUSE_CHANNEL
record.channel = to_channel
job_.change_job_channel(to_channel)
job_.store()

def _validate_state_jobs(self):
if any(job.state in ("done", "started") for job in self):
raise exceptions.ValidationError(
self.env._("Some selected jobs are in invalid states to pause.")
)

def set_channel_pause(self):
self._change_job_pause_channel()
return True
3 changes: 3 additions & 0 deletions queue_job_pause/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build-system]
requires = ["whool"]
build-backend = "whool.buildapi"
2 changes: 2 additions & 0 deletions queue_job_pause/security/ir.model.access.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_queue_channel_pause,access_queue_channel_pause,model_queue_channel_pause,queue_job.group_queue_job_manager,1,1,1,1
1 change: 1 addition & 0 deletions queue_job_pause/wizards/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import queue_jobs_pause_channel
24 changes: 24 additions & 0 deletions queue_job_pause/wizards/queue_jobs_pause_channel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from odoo import fields, models


class QueueChannelPause(models.TransientModel):
_name = "queue.channel.pause"
_description = "Wizard to change jobs to channel paused"

job_ids = fields.Many2many(
comodel_name="queue.job",
string="Jobs",
default=lambda record: record._default_job_ids(),
)

def _default_job_ids(self):
res = False
context = self.env.context
if context.get("active_model") == "queue.job" and context.get("active_ids"):
res = context["active_ids"]
return res

def set_channel_paused(self):
self.job_ids._validate_state_jobs()
self.job_ids.set_channel_pause()
return {"type": "ir.actions.act_window_close"}
33 changes: 33 additions & 0 deletions queue_job_pause/wizards/queue_jobs_pause_channel_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="view_set_channel_pause_job" model="ir.ui.view">
<field name="name">Pause Jobs</field>
<field name="model">queue.channel.pause</field>
<field name="arch" type="xml">
<form string="Pause/Resume Jobs">
<group string="The selected jobs will be paused/resumed.">
<field name="job_ids" nolabel="1" />
</group>
<footer>
<button
name="set_channel_paused"
string="Pause/Resume"
type="object"
class="oe_highlight"
/>
<button string="Cancel" class="oe_link" special="cancel" />
</footer>
</form>
</field>
</record>

<record id="action_set_channel_pause_job" model="ir.actions.act_window">
<field name="name">Pause/Resume Jobs</field>
<field name="res_model">queue.channel.pause</field>
<field name="view_mode">form</field>
<field name="view_id" ref="view_set_channel_pause_job" />
<field name="target">new</field>
<field name="binding_model_id" ref="queue_job.model_queue_job" />
<field name="path">channel_pause_jobs</field>
</record>
</odoo>