What is multi-threading
As we have discussed above that, threads run on same memory location so similarly multiple threads are also live/run on same memory spaces (heap memory). Each thread performs its own specific task.Why we use multi-threading in odoo?
For example we want to insert huge amount of data in database table or we want to perform some huge calculations for all records on button click, in odoo that takes to much time, to improve this process we need multi-threading.Below are the steps to perform multi-threading in odoo on button click.Use Multi Threading to Seed Up Processing in Odoo
1- Import python libraries for multi-threading
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import threading | |
import uuid | |
import openerp | |
import openerp.release | |
import openerp.sql_db | |
import openerp.tools |
2- Create a function that will convert our record ids into the multi dimensional arrays/list. For example if we have 30 records than this function will convert these records into the 10 arrays, and each array has 3 elements. In simple words we will split our data and assign that data in a variable.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def split_list(self,alist, wanted_parts=1): | |
length = len(alist) | |
return [ alist[i*length // wanted_parts: (i+1)*length // wanted_parts] for i in range(wanted_parts) ] | |
if data: | |
A,B,C,D,E,F,G,H,I,J = split_list(data, wanted_parts=10) | |
Output:
[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14, 15], [16, 17, 18], [19, 20, 21], [22, 23, 24], [25, 26, 27], [28, 29, 30]]
3- In next step we will use that variable as an argument to call python multi thread. Remember the number of thread will be same as the number of variable as we have created in step number 1.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
A_calculation = threading.Thread(target=self._run_process, args=(self.id, A)) | |
B_calculation = threading.Thread(target=self._run_process, args=(self.id, B)) | |
C_calculation = threading.Thread(target=self._run_process, args=(self.id, C)) | |
D_calculation = threading.Thread(target=self._run_process, args=(self.id, D)) | |
. | |
. | |
. | |
. | |
. | |
J_calculation = threading.Thread(target=self._run_process, args=(self.id, J)) | |
A_calculation.start() | |
B_calculation.start() | |
C_calculation.start() | |
D_calculation.start() | |
. | |
. | |
. | |
. | |
J_calculation.start() |
4- In each thread we have a function named "_run_process", this function will create a new env (environment) for us to perform processes in multi-threading. For the rest of the code we will use this newly created environment to perform process in batch or multi-threading mode.
multi_threading_to_speed_up_process_in_odoo.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import threading | |
import uuid | |
import openerp | |
import openerp.release | |
import openerp.sql_db | |
import openerp.tools | |
class some_class(models.Model): | |
_name = 'some.class' | |
def button_click_event(self): | |
def split_list(self,alist, wanted_parts=1): | |
length = len(alist) | |
return [ alist[i*length // wanted_parts: (i+1)*length // wanted_parts] for i in range(wanted_parts) ] | |
# data is an object or list | |
if data and data > 10: | |
A,B,C,D,E,F,G,H,I,J = split_list(data, wanted_parts=10) | |
A_calculation = threading.Thread(target=self._run_process, args=(self.id, A)) | |
B_calculation = threading.Thread(target=self._run_process, args=(self.id, B)) | |
C_calculation = threading.Thread(target=self._run_process, args=(self.id, C)) | |
D_calculation = threading.Thread(target=self._run_process, args=(self.id, D)) | |
. | |
. | |
. | |
. | |
. | |
J_calculation = threading.Thread(target=self._run_process, args=(self.id, J)) | |
A_calculation.start() | |
B_calculation.start() | |
C_calculation.start() | |
D_calculation.start() | |
. | |
. | |
. | |
. | |
J_calculation.start() | |
else: | |
A_calculation = threading.Thread(target=self._run_process, args=(self.id,A)) | |
A_calculation.start() | |
def _run_process(self,active_id, list_of_ids): | |
with api.Environment.manage(): | |
with openerp.registry(self.env.cr.dbname).cursor() as new_cr: | |
new_env = api.Environment(new_cr, self.env.uid, self.env.context) | |
#use above new_env to perform multithreading | |
# database insert/huge calculation code goes here |
2 Comments
i called function from _run_process function, every self crash after that .
ReplyDeletehow can i manage it?
can you please share your error log
Delete