diff --git a/queue_job/README.rst b/queue_job/README.rst index 4d55695225..45ec565f2b 100644 --- a/queue_job/README.rst +++ b/queue_job/README.rst @@ -1,7 +1,3 @@ -.. image:: https://odoo-community.org/readme-banner-image - :target: https://odoo-community.org/get-involved?utm_source=readme - :alt: Odoo Community Association - ========= Job Queue ========= @@ -17,7 +13,7 @@ Job Queue .. |badge1| image:: https://img.shields.io/badge/maturity-Mature-brightgreen.png :target: https://odoo-community.org/page/development-status :alt: Mature -.. |badge2| image:: https://img.shields.io/badge/license-LGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png :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 @@ -85,6 +81,36 @@ Features: .. contents:: :local: +Use Cases / Context +=================== + +Odoo treats task synchronously, like when you import a list of products +it will treat each line in one big task. "Queue job" gives you the +ability to detail big tasks in many smaller ones. + +Imagine you have a lot of data to change for thousand orders, you can do +it in one step and cause a heavy load on the server, and this may affect +the performance of Odoo. With queue_job you can divide the work in jobs +and run thousand jobs (one job for each orders). An other benefit is if +one line failed it doesn't block the processing of the others, as the +jobs are independent. Plus you can schedule the jobs and set a number of +retries. + +Here are some community usage examples: + +- Mass sending invoices: + `account_invoice_mass_sending `__ +- Import data in the background: + `base_import_async `__ +- Export data in the background: + `base_export_async `__ +- Generate contract invoices with jobs: + `contract_queue_job `__ +- Generate partner invoices with + jobs:`partner_invoicing_mode `__ +- Process the Sales Automatic Workflow actions with jobs: + `sale_automatic_workflow_job `__ + Installation ============ diff --git a/queue_job/models/queue_job.py b/queue_job/models/queue_job.py index 09851e2734..88e9b3ca78 100644 --- a/queue_job/models/queue_job.py +++ b/queue_job/models/queue_job.py @@ -335,8 +335,8 @@ def button_done(self): return True def button_cancelled(self): - # If job was set to DONE or WAIT_DEPENDENCIES, do not cancel it - states_from = (PENDING, ENQUEUED, FAILED) + # If job was set to DONE do not cancel it + states_from = (WAIT_DEPENDENCIES, PENDING, ENQUEUED, FAILED) result = _("Cancelled by {}").format(self.env.user.name) records = self.filtered(lambda job_: job_.state in states_from) records._change_job_state(CANCELLED, result=result) @@ -354,8 +354,11 @@ def _message_post_on_failure(self): # at every job creation domain = self._subscribe_users_domain() base_users = self.env["res.users"].search(domain) + suscribe_job_creator = self._subscribe_job_creator() for record in self: - users = base_users | record.user_id + users = base_users + if suscribe_job_creator: + users |= record.user_id record.message_subscribe(partner_ids=users.mapped("partner_id").ids) msg = record._message_failed_job() if msg: @@ -372,6 +375,14 @@ def _subscribe_users_domain(self): domain.append(("company_id", "in", companies.ids)) return domain + @api.model + def _subscribe_job_creator(self): + """ + Whether the user that created the job should be subscribed to the job, + in addition to users determined by `_subscribe_users_domain` + """ + return True + def _message_failed_job(self): """Return a message which will be posted on the job when it is failed. diff --git a/queue_job/readme/CONTEXT.md b/queue_job/readme/CONTEXT.md new file mode 100644 index 0000000000..ca9cda79d6 --- /dev/null +++ b/queue_job/readme/CONTEXT.md @@ -0,0 +1,15 @@ +Odoo treats task synchronously, like when you import a list of products it will treat each line in one big task. +"Queue job" gives you the ability to detail big tasks in many smaller ones. + +Imagine you have a lot of data to change for thousand orders, you can do it in one step and cause a heavy load on the server, and this may affect the performance of Odoo. With queue_job you can divide the work in jobs and run thousand jobs (one job for each orders). +An other benefit is if one line failed it doesn't block the processing of the others, as the jobs are independent. +Plus you can schedule the jobs and set a number of retries. + +Here are some community usage examples: + +* Mass sending invoices: [account_invoice_mass_sending](https://github.com/OCA/account-invoicing/tree/17.0/account_invoice_mass_sending) +* Import data in the background: [base_import_async](https://github.com/OCA/queue/tree/17.0/base_import_async) +* Export data in the background: [base_export_async](https://github.com/OCA/queue/tree/17.0/base_export_async) +* Generate contract invoices with jobs: [contract_queue_job](https://github.com/OCA/contract/tree/17.0/contract_queue_job) +* Generate partner invoices with jobs:[partner_invoicing_mode](https://github.com/OCA/account-invoicing/tree/17.0/partner_invoicing_mode) +* Process the Sales Automatic Workflow actions with jobs: [sale_automatic_workflow_job](https://github.com/OCA/sale-workflow/tree/17.0/sale_automatic_workflow_job) diff --git a/queue_job/static/description/index.html b/queue_job/static/description/index.html index a04be050e2..a99d1ce2f8 100644 --- a/queue_job/static/description/index.html +++ b/queue_job/static/description/index.html @@ -3,7 +3,7 @@ -README.rst +Job Queue -
+
+

Job Queue

- - -Odoo Community Association - -
-

Job Queue

-

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

+

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

This addon adds an integrated Job Queue to Odoo.

It allows to postpone method calls executed asynchronously.

Jobs are executed in the background by a Jobrunner, in their own @@ -420,41 +415,70 @@

Job Queue

Table of contents

+
+

Use Cases / Context

+

Odoo treats task synchronously, like when you import a list of products +it will treat each line in one big task. “Queue job” gives you the +ability to detail big tasks in many smaller ones.

+

Imagine you have a lot of data to change for thousand orders, you can do +it in one step and cause a heavy load on the server, and this may affect +the performance of Odoo. With queue_job you can divide the work in jobs +and run thousand jobs (one job for each orders). An other benefit is if +one line failed it doesn’t block the processing of the others, as the +jobs are independent. Plus you can schedule the jobs and set a number of +retries.

+

Here are some community usage examples:

+ +
-

Installation

+

Installation

Be sure to have the requests library.

-

Configuration

+

Configuration

  • Using environment variables and command line:
    • Adjust environment variables (optional):
-

Usage

+

Usage

To use this module, you need to:

  1. Go to Job Queue menu
-

Developers

+

Developers

-

Delaying jobs

+

Delaying jobs

The fast way to enqueue a job for a method is to use with_delay() on a record or model:

@@ -645,7 +669,7 @@ 

Delaying jobs

-

Enqueing Job Options

+

Enqueing Job Options

  • priority: default is 10, the closest it is to 0, the faster it will be executed
  • @@ -664,7 +688,7 @@

    Enqueing Job Options

-

Configure default options for jobs

+

Configure default options for jobs

In earlier versions, jobs could be configured using the @job decorator. This is now obsolete, they can be configured using optional queue.job.function and queue.job.channel XML records.

@@ -792,7 +816,7 @@

Configure default options for job delaying any jobs.

-

Testing

+

Testing

Asserting enqueued jobs

The recommended way to test jobs, rather than running them directly and synchronously is to split the tests in two parts:

@@ -907,7 +931,7 @@

Testing

synchronously

-

Patterns

+

Patterns

Through the time, two main patterns emerged:

  1. For data exposed to users, a model should store the data and the @@ -934,16 +958,16 @@

    Patterns

-

Known issues / Roadmap

+

Known issues / Roadmap

  • After creating a new database or installing queue_job on an existing database, Odoo must be restarted for the runner to detect it.
-

Changelog

+

Changelog

-

Bug Tracker

+

Bug Tracker

Bugs are tracked on GitHub 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 @@ -962,16 +986,16 @@

Bug Tracker

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

-

Credits

+

Credits

-

Authors

+

Authors

  • Camptocamp
  • ACSONE SA/NV
-

Contributors

+

Contributors

-

Other credits

+

Other credits

The migration of this module from 17.0 to 18.0 was financially supported by Camptocamp.

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -1011,6 +1035,5 @@

Maintainers

-
diff --git a/queue_job/tests/test_wizards.py b/queue_job/tests/test_wizards.py index 7738836d2f..54718f658a 100644 --- a/queue_job/tests/test_wizards.py +++ b/queue_job/tests/test_wizards.py @@ -69,18 +69,13 @@ def test_04_requeue_forbidden(self): def test_05_cancel_forbidden(self): wizard = self._wizard("queue.jobs.to.cancelled") - # State WAIT_DEPENDENCIES is not cancelled - self.job.state = "wait_dependencies" - wizard.set_cancelled() - self.assertEqual(self.job.state, "wait_dependencies") - # State DONE is not cancelled self.job.state = "done" wizard.set_cancelled() self.assertEqual(self.job.state, "done") - # State PENDING, ENQUEUED or FAILED will be cancelled - for test_state in ("pending", "enqueued"): + # State PENDING, ENQUEUED, WAIT_DEPENDENCIES or FAILED will be cancelled + for test_state in ("pending", "enqueued", "wait_dependencies", "failed"): self.job.state = test_state wizard.set_cancelled() self.assertEqual(self.job.state, "cancelled") @@ -99,7 +94,7 @@ def test_06_done_forbidden(self): self.assertEqual(self.job.state, "cancelled") # State WAIT_DEPENDENCIES, PENDING, ENQUEUED or FAILED will be set to DONE - for test_state in ("wait_dependencies", "pending", "enqueued"): + for test_state in ("wait_dependencies", "pending", "enqueued", "failed"): self.job.state = test_state wizard.set_done() self.assertEqual(self.job.state, "done") diff --git a/queue_job/views/queue_job_views.xml b/queue_job/views/queue_job_views.xml index fba121b21a..7d9e75bdd3 100644 --- a/queue_job/views/queue_job_views.xml +++ b/queue_job/views/queue_job_views.xml @@ -24,7 +24,7 @@ />