Enable Dark Mode!
an-overview-of-batch-processing-and-multiprocessing-in-odoo-16.jpg
By: Abhin K

An Overview of Batch Processing & Multiprocessing in Odoo 16

Technical Odoo 16

In the world of Odoo development, efficient data processing is a cornerstone. One key strategy is Batch Processing, which involves breaking down large tasks into smaller, manageable portions. This approach not only improves performance but also enhances resource allocation. In this blog, we delve into the fundamental concept of Batch Processing and its role in optimizing data operations within Odoo. Additionally, we touch on Parallel Processing, where multiple tasks run concurrently, boosting efficiency further.

Parallelism and Multiprocessing

Parallelism and multiprocessing are techniques used to achieve concurrent execution of tasks in a computer program, with the goal of improving performance by leveraging multiple CPU cores or processors. Both approaches enable a program to execute multiple tasks simultaneously, but they differ in their implementation and usage.
Parallelism 
-Parallelism refers to the concept of breaking down a larger task into smaller sub-tasks that can be executed concurrently on separate processors or cores.
-It involves running multiple threads or processes simultaneously, with each thread or process handling a specific part of the overall task.
-Parallelism is commonly used in multi-threaded applications, where different threads work on different parts of the problem simultaneously.
-It can be implemented using programming techniques like multithreading in Python's threading` module or using parallel processing libraries like `concurrent.futures`.
 with concurrent.futures.ThreadPoolExecutor() as executor:
            a = executor.map(self.create_sale,
                             [random.choice(partner_id_list) for _ in range(self.value_3)])
Multiprocessing :
- Multiprocessing is a specific form of parallelism that involves the creation of multiple processes to perform tasks concurrently.
- Each process has its memory space and runs independently, making it suitable for tasks that require heavy CPU usage or tasks that can be easily divided into independent units.
- Unlike multithreading, multiprocessing allows each process to utilize a separate CPU core, providing a more significant performance boost for CPU-bound tasks.
- In Python, multiprocessing can be achieved using the `multiprocessing` module, which provides classes and functions for creating and managing multiple processes.
   with concurrent.futures.ProcessPoolExecutor() as executor:
            a = executor.map(self.create_sale,
                             [random.choice(partner_id_list) for _ in range(self.value_3)])
Key Differences :

1.Resource Isolation 

   - In parallelism, multiple threads or tasks run within the same process and share the same memory space. This can lead to potential issues like data race conditions.
   - In multiprocessing, each process runs in its isolated memory space, avoiding shared data problems and providing more robustness.

2.Performance 

   - Parallelism may not provide a significant performance boost for CPU-bound tasks since Python's Global Interpreter Lock (GIL) can limit true parallel execution of threads.
   - Multiprocessing can effectively utilize multiple CPU cores and provides better performance for CPU-intensive tasks.

3.Ease of Use 

   - Parallelism using multithreading is relatively easier to implement, as it involves sharing data within the same memory space.
   - Multiprocessing requires more consideration for inter-process communication and synchronization since processes are isolated.

4.Use Cases 

   - Parallelism is suitable for I/O-bound tasks, where waiting for I/O operations (e.g., file I/O, network requests) can be done concurrently without consuming much CPU.
   - Multiprocessing is ideal for CPU-bound tasks, where multiple independent computations can be performed simultaneously on separate cores.
In conclusion, both parallelism and multiprocessing offer ways to achieve concurrent execution in Python. Parallelism is often used for I/O-bound tasks, while multiprocessing is more effective for CPU-bound tasks. The choice between the two depends on the specific requirements of the program and the nature of the tasks being performed.
Although This is a useful tool, we don't need to explicitly use these functions ourselves because Odoo has already built the framework with these concepts in mind. Any functions we write will automatically utilize these functionalities provided by Odoo's built-in features. This allows us to focus on implementing the specific business logic and leave the underlying framework mechanics to Odoo.
Batch Processing
Batch processing is a technique used to process large volumes of data in smaller, manageable chunks or batches rather than processing the entire dataset at once. This approach is commonly used when dealing with large datasets that do not fit into memory or when processing all the data at once would be inefficient or time-consuming. Batch processing helps optimize resource utilization, reduce memory requirements, and improve overall performance. It is widely used in various domains, including data processing, data analysis, and report generation.
Elaborating on batch processing:

1.Dividing Data into Batches

In batch processing, the large dataset is divided into smaller batches of manageable size. Each batch typically contains a fixed number of records or a specific time window of data. The size of the batch depends on factors like available memory, processing resources, and the nature of the task.

2. Processing in Chunks:

Once the data is divided into batches, the processing logic is applied to each batch independently. The application processes one batch at a time, completing the operations on that batch before moving on to the next one. This way, the system can handle large datasets without overloading resources.

3. Resource Management

Batch processing allows for efficient resource management. Since only a limited amount of data is processed at a time, memory usage and processing resources can be better controlled. This prevents memory exhaustion and minimizes the risk of system crashes due to overwhelming data volumes.

4. Error Handling and Recovery

Batch processing provides better error handling and recovery mechanisms. If an error occurs during processing, it can be isolated to a specific batch, making it easier to identify and troubleshoot the issue. Additionally, if the process is interrupted for any reason, it can be resumed from the last successfully processed batch.

5. Parallel Processing

In some cases, batch processing can be combined with parallelism or multiprocessing techniques to further optimize performance. Parallel batch processing involves dividing each batch into smaller chunks and processing them concurrently across multiple cores or threads.

6. Use Cases

Batch processing is commonly used for tasks like data extraction, data transformation, and data loading (ETL), report generation, data backup, and data migration. For example, batch processing is used in a data warehouse to extract data from multiple sources, transform it into a common format, and load it into the data warehouse at regular intervals.

7. Time and Resource Efficiency

Batch processing can significantly improve the efficiency of data processing tasks. By breaking down a large task into smaller manageable units it reduces processing time, lowers the risk of system overload, and ensures better utilization of resources.

8. Considerations

While batch processing is advantageous for large datasets, it may not be suitable for real-time or time-critical applications. For real-time processing, streaming and event-driven architectures are more appropriate.
In summary, batch processing is a powerful technique for handling large datasets efficiently. By dividing data into manageable batches, processing tasks become more scalable, resource-efficient, and manageable. It is an essential tool in data-intensive applications and data processing pipelines, helping organizations to derive valuable insights and make informed decisions from their data.
Here is an example of utilizing batch processing:
def create_sale(self):
        """Creates 'number_of_order' number of sale records"""
        partner_id_list = self._partners()
        orders_data = [{
            'partner_id': random.choice(partner_id_list),
            'state': random.choice(['draft', 'sent']),
            'order_line': [
                Command.create({
                    'product_template_id': rec.product_tmpl_id.id,
                    'product_id': rec.id,
                    'name': rec.name,
                    'product_uom_qty': random.randint(1, 5),
                    'price_unit': rec.lst_price,
                }) for rec in self._product_generator()
            ]
        } for _ in range(self.number_of_order)]
        self._create_records('sale.order', orders_data)
This function creates ‘n’ number of records based on the 'number_of_order'. It also generates random  products for the order_lines. 
def _create_records(self, model, orders_data):
        """Creates record"""
        sub_lists = self._grouper(orders_data, 5) if len(
            orders_data) > 4 else orders_data
        for sub in sub_lists:
            self.env[model].create(sub)
The reason why the `_grouper()` function is used is that if the `order_data` contains a large number of records, the time it takes to create those records will be significantly higher. Creating each record one at a time can also take a considerable amount of time. Therefore, the `_grouper()` function is used to split the `order_data` into small batches of data, which will be the sweet spot amount of data that the `create` function can efficiently handle. By using smaller batches, the record creation process becomes much faster and more optimized.
def _grouper(self, iterable, sublist_length, fillvalue=None):
        """Groups the sale creation for a better performance"""
        args = [iter(iterable)] * sublist_length
        return zip_longest(*args, fillvalue=fillvalue)
Here, when creating 1000 sale order records, using the `_grouper()` function took around 30 seconds. In comparison, using a list comprehension method took around 75 seconds, and using a normal method took around 80 seconds. It's evident that using the `_grouper()` function resulted in a significant performance improvement, making the record creation process much faster compared to the other methods.
Each situation may have its own unique requirements and data processing needs. In most cases, the normal methods provided by Odoo will suffice, and you may not need to handle batch processing explicitly. However, in specific scenarios dealing with a large amount of data or complex operations, the batch processing functionality like the _grouper() function can be a valuable tool to optimize performance and efficiency. Understanding your specific use case and choosing the appropriate method to achieve the best results is essential.


If you need any assistance in odoo, we are online, please chat with us.



0
Comments



Leave a comment



whatsapp_icon
location

Calicut

Cybrosys Technologies Pvt. Ltd.
Neospace, Kinfra Techno Park
Kakkancherry, Calicut
Kerala, India - 673635

location

Kochi

Cybrosys Technologies Pvt. Ltd.
1st Floor, Thapasya Building,
Infopark, Kakkanad,
Kochi, India - 682030.

location

Bangalore

Cybrosys Techno Solutions
The Estate, 8th Floor,
Dickenson Road,
Bangalore, India - 560042

Send Us A Message