From 5a3095673f169bb792223942034105ee8980bffe Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Wed, 20 Mar 2013 16:34:30 +0100 Subject: [PATCH] [FIX] subscription: prevent lockup during cron job execution Due to the way cron jobs are executed in multi-process environments, the cron arbiter holds an exclusive lock on the cron task row in the database. During the course of the subscription cron jobs execution they attempt to alter a record that has a FK towards the cron task row, effectively deadlocking the whole cron processing thread. The fix is rather hackish: remove the explicit FK constraint from the subscription model towards ir.cron - this prevent PostgreSQL from requesting an exclusive lock and triggering a deadlock. This is only a temporary solution, the subscription module should be rewritten for the next stable release. bzr revid: odo@openerp.com-20130320153430-bho6ou8b7ziohcb0 --- addons/subscription/subscription.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/addons/subscription/subscription.py b/addons/subscription/subscription.py index d181e97e8f0..92bde135bc6 100644 --- a/addons/subscription/subscription.py +++ b/addons/subscription/subscription.py @@ -85,6 +85,17 @@ class subscription_subscription(osv.osv): 'state': lambda *a: 'draft' } + def _auto_end(self, cr, context=None): + super(subscription_subscription, self)._auto_end(cr, context=context) + # drop the FK from subscription to ir.cron, as it would cause deadlocks + # during cron job execution. When model_copy() tries to write() on the subscription, + # it has to wait for an ExclusiveLock on the cron job record, but the latter + # is locked by the cron system for the duration of the job! + # FIXME: the subscription module should be reviewed to simplify the scheduling process + # and to use a unique cron job for all subscriptions, so that it never needs to + # be updated during its execution. + cr.execute("ALTER TABLE %s DROP CONSTRAINT %s" % (self._table, '%s_cron_id_fkey' % self._table)) + def set_process(self, cr, uid, ids, context=None): for row in self.read(cr, uid, ids, context=context): mapping = {'name':'name','interval_number':'interval_number','interval_type':'interval_type','exec_init':'numbercall','date_init':'nextcall'}