From f877d534c7e15b589511cac14f79f6dcdab142ec Mon Sep 17 00:00:00 2001 From: Eileen Date: Fri, 30 May 2014 00:11:23 -0400 Subject: [PATCH] CRM-12856 hack to stop problems arising from mis-use of locks - need to review correct approach --- CRM/Core/Lock.php | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/CRM/Core/Lock.php b/CRM/Core/Lock.php index eef6cb6ed8..134ba1ab0b 100644 --- a/CRM/Core/Lock.php +++ b/CRM/Core/Lock.php @@ -66,6 +66,15 @@ class CRM_Core_Lock { else { $this->_name = $database . '.' . $domainID . '.' . $name; } + CRM_Core_Error::debug_log_message('trying to construct lock for ' . $this->_name); + static $jobLog = FALSE; + if($jobLog && CRM_Core_DAO::singleValueQuery("SELECT IS_USED_LOCK( '{$jobLog}')")) { + return $this->hackyHandleBrokenCode($jobLog); + } + if(stristr($name, 'civimail.job.')) { + $jobLog = $this->_name; + } + //CRM_Core_Error::debug_var('backtrace', debug_backtrace()); $this->_timeout = $timeout !== NULL ? $timeout : self::TIMEOUT; $this->acquire(); @@ -76,6 +85,8 @@ class CRM_Core_Lock { } function acquire() { + + CRM_Core_Error::debug_log_message('aquire lock for ' . $this->_name); if (!$this->_hasLock) { $query = "SELECT GET_LOCK( %1, %2 )"; $params = array(1 => array($this->_name, 'String'), @@ -108,5 +119,27 @@ class CRM_Core_Lock { function isAcquired() { return $this->_hasLock; } + + /** + * CRM-12856 locks were originally set up for jobs, but the concept was extended to caching & groups without + * understanding that would undermine the job locks (because grabbing a lock implicitly releases existing ones) + * this is all a big hack to mitigate the impact of that - but should not be seen as a fix. Not sure correct fix + * but maybe locks should be used more selectively? Or else we need to handle is some cool way that Tim is yet to write :-) + * if we are running in the context of the cron log then we would rather die (or at least let our process die) + * than release that lock - so if the attempt is being made by setCache or something relatively trivial + * we'll just return TRUE, but if it's another job then we will crash as that seems 'safer' + * + * @param string $jobLog + * @throws CRM_Core_Exception + * @return boolean + */ + function hackyHandleBrokenCode($jobLog) { + if(stristr($this->_name, 'job')) { + throw new CRM_Core_Exception('lock aquisition for ' . $this->_name . 'attempted when ' . $jobLog . 'is not released'); + } + CRM_Core_Error::debug_log_message('(CRM-12856) faking lock for ' . $this->_name); + $this->_hasLock = TRUE; + return TRUE; + } } -- 2.25.1