Odoo is a robust suite of business applications, including CRM, sales, project management, warehouse management, manufacturing, and accounting, built using Python and PostgreSQL. In certain scenarios, particularly when handling long-running processes or operations that need asynchronous execution, threading can significantly enhance the performance and responsiveness of Odoo applications.
Threading allows multiple threads to run concurrently within the same process, sharing the same memory space. This capability is especially beneficial in Odoo for executing background tasks without disrupting the main application flow. This blog post will explore how to implement threading in Odoo and provide a simple example to illustrate its usage.
Threading in Odoo offers several key advantages, making it a valuable tool for enhancing application performance. By enabling the simultaneous execution of multiple tasks, threading can significantly boost the overall performance of Odoo applications. It also contributes to a more responsive user interface by offloading long-running tasks to separate threads, ensuring the UI remains smooth and uninterrupted. Additionally, threading allows for more efficient resource utilization, as it optimizes system resources by running tasks in parallel, leading to faster processing times and improved application efficiency.
Let's explore threading with a simple and basic example.
We have a scenario in Odoo 17 where there's a button on the sale order. When clicked, it triggers some custom processes that run for 15 seconds.
Let's create a button in the sale order view. We'll add this view file to the module's views folder and include the path in the __manifest__.py as well.
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!-- Added a button to test thread in sale.order-->
<record id="view_sale_order_form_custom_thread" model="ir.ui.view">
<field name="name">sale.order.form.custom.thread</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<xpath expr="//button[@name='action_confirm']" position="after">
<button name="action_thread" type="object" string="Test Thread"
class="oe_highlight"/>
</xpath>
</field>
</record>
</odoo>
Next, we'll define the button's action in the sale order by inheriting the model. Add the corresponding Python file in the models folder and ensure the __init__.py files are updated accordingly.
import time
from odoo import models
class SaleOrder(models.Model):
_inherit = 'sale.order'
def action_thread(self):
"""Method for Thread action Button"""
time.sleep(15)
# The print function works only after the sleep function ends.
print('finish')
When we click the 'Test Thread' button, the sleep function will execute for the specified duration. During this time, the UI is interrupted due to loading.
We can resolve this issue by using threading. To do this, we created a thread class by importing Thread from the threading module.
from threading import Thread
import time
class MyThread(Thread):
def __init__(self):
""" Function to Initialize the thread"""
Thread.__init__(self)
def run(self):
time.sleep(15)
print('finish')
We added a thread class with an __init__ and run function. When the thread starts, it first calls the __init__ function to initialize the thread, followed by the run function. In this setup, we've placed the sleep function within the thread's run function.
We can see how to start the thread instance within our button action.
from .my_thread import MyThread
from odoo import models
class SaleOrder(models.Model):
_inherit = 'sale.order'
def action_thread(self):
"""Method for Thread action Button"""
my_thread = MyThread()
my_thread.start()
Import the Thread class into the Sale order, Then we store the instance of MyThread in a variable named my_thread and then execute the code to start this instance.
As a result, the sleep function within the MyThread class will execute without interrupting the UI.
After clicking the button, the sleep function executes without affecting the UI's interactivity. The message "finished" is printed 15 seconds after the button is clicked.
We can also use the my_thread.join() function to wait for the thread to complete its execution.
In this blog post, we covered the basics of threading in Odoo applications. We explored its benefits, provided a step-by-step guide for implementation, and demonstrated a simple example. While this introduction helps enhance the performance and responsiveness of your Odoo applications, there is much more to learn about threading. We encourage you to delve deeper into threading concepts to fully leverage its potential in your projects for even greater performance and responsiveness.
To read more about Threading Mutex in Python, refer to our blog Threading Mutex in Python.