OdooGap Blog / Background processes in Odoo

Background processes in Odoo


How to run threads in Odoo


Background Processes in Odoo

Software simplifies our lives, but we know that it’s not without its challenges. Don’t worry, we’re here to help you manage certain obstacles and when it comes to Odoo development, it’s easier than you think.
Have you ever got a timeout while doing some long operation or some parallel call in the main process flow?
You will have a few options to handle this and prevent future problems, which we’ll explain below.

Set Up a Scheduled Action

The most typical is setting up a scheduled action. Make it process for a reasonable interval to see if it solves the problem.

Use the Server Code

Also, you can look into the server code and learn to address the challenges with Odoo background processes there. Thanks to programming languages such as Python, it’s fairly simple to fix timeout problems with coding.

Here is a practical example of the procurement module v9.0:

def _procure_calculation_all(self, cr, uid, ids, context=None):
    """
    @param self: The object pointer.
    @param cr: A database cursor
    @param uid: ID of the user currently logged in
    @param ids: List of IDs selected
    @param context: A standard dictionary
    """
    with Environment.manage():
        proc_obj = self.pool.get('procurement.order')
        #As this function is in a new thread, i need to open a new cursor, because the old one may be closed
        new_cr = self.pool.cursor()
        scheduler_cron_id = self.pool['ir.model.data'].get_object_reference(new_cr, SUPERUSER_ID, 'procurement', 'ir_cron_scheduler_action')[1]
        # Avoid to run the scheduler multiple times in the same time
        try:
            with tools.mute_logger('openerp.sql_db'):
                new_cr.execute("SELECT id FROM ir_cron WHERE id = %s FOR UPDATE NOWAIT", (scheduler_cron_id,))
        except Exception:
            _logger.info('Attempt to run procurement scheduler aborted, as already running')
            new_cr.rollback()
            new_cr.close()
            return {}
        user = self.pool.get('res.users').browse(new_cr, uid, uid, context=context)
        comps = [x.id for x in user.company_ids]
        for comp in comps:
            proc_obj.run_scheduler(new_cr, uid, use_new_cursor=new_cr.dbname, company_id = comp, context=context)
        #close the new cursor
        new_cr.close()
        return {}


Then, finally, the function that triggers the calculation associated with a button on the UI:

def procure_calculation(self, cr, uid, ids, context=None):
    """
    @param self: The object pointer.
    @param cr: A database cursor
    @param uid: ID of the user currently logged in
    @param ids: List of IDs selected
    @param context: A standard dictionary
    """
    threaded_calculation = threading.Thread(target=self._procure_calculation_all, args=(cr, uid, ids, context))
    threaded_calculation.start()
    return {'type': 'ir.actions.act_window_close'}


Additional Tools

If you need to do complex and more time consuming workflows, we suggest using other tools. Just get in touch with the Odoo development team, because we have a solution for each situation.

Hopefully, now you're able to deal with timeouts like an expert.

If you run into any problems, let us know. If everything went smoothly, glad we could help! Or perhaps you have tips for others about Odoo background processes? Please use our social media platforms to share your thoughts.

Talk to an Odoo Development Expert


Other articles



Manage your Human Resources with Odoo

Inventory Management Software

COVID-19 Saliva Testing Plaform - CoVTec