跳转到主要内容

工作队列

项目描述

Mature License: LGPL-3 OCA/queue Translate me on Weblate Try me on Runboat

此插件为Odoo添加了集成的作业队列。

它允许延迟执行异步的方法调用。

作业由Jobrunner在后台执行,它们在自己的事务中执行。

示例

from odoo import models, fields, api

class MyModel(models.Model):
   _name = 'my.model'

   def my_method(self, a, k=None):
       _logger.info('executed with a: %s and k: %s', a, k)


class MyOtherModel(models.Model):
    _name = 'my.other.model'

    def button_do_stuff(self):
        self.env['my.model'].with_delay().my_method('a', k=2)

在上面的代码片段中,当我们调用button_do_stuff时,一个将方法及其参数捕获的作业将被延迟。一旦Jobrunner有空闲槽位,它就会执行,如果没有其他作业在运行,这可能几乎是瞬间的。

特性

  • 作业视图,作业存储在PostgreSQL中

  • Jobrunner:执行作业,由于PostgreSQL的NOTIFY而高效

  • 通道:为根通道及其子通道提供容量,并在其中隔离作业。例如,可以将重作业限制为一次执行一个,而轻作业可以一次执行四个。

  • 重试:通过引发一种类型的异常来重试作业的能力

  • 重试模式:前三次尝试,10秒后重试,接下来的五次尝试,1分钟后重试,……

  • 作业属性:优先级,预计到达时间(ETA),自定义描述,重试次数

  • 相关操作:在作业视图中链接一个操作,例如打开作业相关的记录

目录

安装

确保已安装requests库。

配置

  • 使用环境变量和命令行

    • 调整环境变量(可选)

      • ODOO_QUEUE_JOB_CHANNELS=root:4 或任何其他通道配置。默认为 root:1

      • 如果未设置 xmlrpc_port,则 ODOO_QUEUE_JOB_PORT=8069

    • 使用 --load=web,queue_job--workers 大于 1 的参数启动 Odoo。 [1]

  • 使用 Odoo 配置文件

[options]
(...)
workers = 6
server_wide_modules = web,queue_job

(...)
[queue_job]
channels = root:2
  • 通过检查 odoo 日志文件来确认运行者是否正确启动

...INFO...queue_job.jobrunner.runner: starting
...INFO...queue_job.jobrunner.runner: initializing database connections
...INFO...queue_job.jobrunner.runner: queue job runner ready for db <dbname>
...INFO...queue_job.jobrunner.runner: database connections ready
  • 创建作业(例如使用 base_import_async)并观察它们立即并行启动。

  • 提示:要启用队列作业的调试日志,请使用 --log-handler=odoo.addons.queue_job:DEBUG

使用

要使用此模块,您需要

  1. 转到 作业队列 菜单

开发者

配置作业的默认选项

在早期版本中,可以使用 @job 装饰器配置作业。现在这已经过时了,可以使用可选的 queue.job.functionqueue.job.channel XML 记录来配置。

频道示例

<record id="channel_sale" model="queue.job.channel">
    <field name="name">sale</field>
    <field name="parent_id" ref="queue_job.channel_root" />
</record>

作业函数示例

<record id="job_function_sale_order_action_done" model="queue.job.function">
    <field name="model_id" ref="sale.model_sale_order" />
    <field name="method">action_done</field>
    <field name="channel_id" ref="channel_sale" />
    <field name="related_action" eval='{"func_name": "custom_related_action"}' />
    <field name="retry_pattern" eval="{1: 60, 2: 180, 3: 10, 5: 300}" />
</record>

name 的一般形式为: <model.name>.method

频道、相关动作和重试模式选项是可选的,它们在下面的文档中有说明。

当编写模块时,如果 2 个或更多模块添加了具有相同名称(和频道对于频道)的作业函数或频道,它们将合并到同一个记录中,即使它们有不同的 xmlid。在卸载时,当所有使用它的模块都卸载时,合并的记录将被删除。

作业函数:频道

作业将被延迟的频道。默认频道是 root

作业函数:相关动作

“相关动作”在作业视图上作为一个按钮出现。该按钮将执行定义的动作。

默认动作是打开与作业相关的记录的视图(当只有一个记录时为表单视图,为多个记录时为列表视图)。在许多情况下,默认的相关动作已经足够,不需要定制,但可以通过在作业函数中提供一个字典来定制。

{
    "enable": False,
    "func_name": "related_action_partner",
    "kwargs": {"name": "Partner"},
}
  • enable:当 False 时,按钮没有效果(默认:True

  • func_name:返回动作的 queue.job 上方法的名称

  • kwargs:传递给相关动作方法的额外参数

相关动作代码示例

class QueueJob(models.Model):
    _inherit = 'queue.job'

    def related_action_partner(self, name):
        self.ensure_one()
        model = self.model_name
        partner = self.records
        action = {
            'name': name,
            'type': 'ir.actions.act_window',
            'res_model': model,
            'view_type': 'form',
            'view_mode': 'form',
            'res_id': partner.id,
        }
        return action

作业函数:重试模式

当一个作业因可重试的错误类型失败时,它会自动稍后重试。默认情况下,重试总是 10 分钟后。

可以在作业函数上配置重试模式。一个模式代表的是“从 X 次尝试开始,延迟到 Y 秒”。它是一个字典,键是尝试次数,值是延迟秒数的整数。

{
    1: 10,
    5: 20,
    10: 30,
    15: 300,
}

基于此配置,我们可以知道

  • 前 5 次重试延迟 10 秒

  • 第 5 到 10 次重试延迟 20 秒

  • 第 10 到 15 次重试延迟 30 秒

  • 所有后续重试延迟 5 分钟

作业上下文

作业记录集的上下文,或任何作为作业参数传递的记录集,根据允许列表转移到作业中。

为了向后兼容,默认允许列表为空。允许列表可以在 Base._job_prepare_context_before_enqueue_keys 中自定义。

示例

class Base(models.AbstractModel):

    _inherit = "base"

    @api.model
    def _job_prepare_context_before_enqueue_keys(self):
        """Keys to keep in context of stored jobs

        Empty by default for backward compatibility.
        """
        return ("tz", "lang", "allowed_company_ids", "force_company", "active_test")

绕过正在运行的 Odoo 上的作业

在开发(例如:连接器模块)时,您可能希望绕过队列作业并立即运行您的代码。

为此,您可以在您的环境中设置 TEST_QUEUE_JOB_NO_DELAY=1

绕过测试中的作业

在编写与作业相关的方法的测试时,总是很难处理延迟的记录集。为了使您的测试生活更加轻松,您可以在上下文中设置 test_queue_job_no_delay=True

提示:您可以在测试用例级别这样做

@classmethod
def setUpClass(cls):
    super().setUpClass()
    cls.env = cls.env(context=dict(
        cls.env.context,
        test_queue_job_no_delay=True,  # no jobs thanks
    ))

然后所有测试都会同步执行作业方法,而不延迟任何作业。

已知问题/路线图

  • 在创建新的数据库或在现有数据库上安装 queue_job 之后,Odoo 必须重新启动,以便运行器检测到它。

  • 当 Odoo 正常关闭时,它会等待正在运行的任务完成。然而,当 Odoo 服务器崩溃或被强制停止时,正在运行的任务会在运行器没有机会知道它们已被中止的情况下中断。在这种情况下,作业可能在 Odoo 服务器停止后仍处于 已开始已入队 状态。由于运行器无法知道它们是否实际正在运行,也不知道是否安全地重新启动作业,因此它不会尝试自动重新启动它们。因此,这些过时的作业会填满运行队列,并阻止其他作业启动。因此,您必须手动重新排队,无论是从作业视图,还是通过运行以下 SQL 语句 在启动 Odoo 之前

update queue_job set state='pending' where state in ('started', 'enqueued')

变更日志

下一页

  • [ADD] 将作业运行器作为工作进程而不是主进程中的线程运行(当使用 –workers > 0 运行时)

  • [REF] @job@related_action 已弃用,任何方法都可以延迟,并使用 queue.job.function 记录配置

13.0.1.2.0 (2020-03-10)

  • 修复多公司访问规则

13.0.1.1.0 (2019-11-01)

重要:许可证已从 AGPL3 更改为 LGPL3。

  • 移除已弃用的默认公司方法(详细信息请参阅 #180

13.0.1.0.0 (2019-10-14)

  • [MIGRATION] 从 rev. 0138cd0 的 12.0 分支

错误追踪器

错误在 GitHub Issues 上跟踪。如有问题,请检查是否已报告您的问题。如果您是第一个发现的人,请通过提供详细且受欢迎的 反馈 帮助我们解决问题。

请不要直接联系贡献者以寻求支持或技术问题的帮助。

致谢

作者

  • Camptocamp

  • ACSONE SA/NV

贡献者

维护者

此模块由 OCA 维护。

Odoo Community Association

OCA,或 Odoo 社区协会,是一个非营利组织,其使命是支持 Odoo 功能的协作开发并推广其广泛使用。

当前 维护者

guewen

此模块是 GitHub 上的 OCA/queue 项目的组成部分。

欢迎您贡献力量。了解更多信息,请访问 https://odoo-community.org/page/Contribute

项目详情


发布历史 发布通知 | RSS 源

下载文件

下载适用于您平台的文件。如果您不确定该选择哪个,请了解更多关于安装包的信息。

源代码分发

此版本没有可用的源代码分发文件。请参阅生成分发存档的教程

构建分发

odoo13_addon_queue_job-13.0.3.11.2-py3-none-any.whl (113.3 kB 查看哈希值)

上传时间 Python 3

由以下机构支持