Created
March 13, 2014 23:16
-
-
Save wcurtis/9539178 to your computer and use it in GitHub Desktop.
Magento Lock Model for Preventing Cron Job Overlap
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
<?php | |
/** | |
* Lock manager to ensure our cron doesn't run twice at the same time. | |
* | |
* Inspired by the lock mechanism in Mage_Index_Model_Process | |
* | |
* Usage: | |
* | |
* $lock = Mage::getModel('stcore/cron_lock'); | |
* | |
* if (!$lock->isLocked()) { | |
* $lock->lock(); | |
* // Do your stuff | |
* $lock->unlock(); | |
* } | |
*/ | |
class ST_Core_Model_Cron_Lock extends Varien_Object | |
{ | |
/** | |
* Process lock properties | |
*/ | |
protected $_isLocked = null; | |
protected $_lockFile = null; | |
/** | |
* Get lock file resource | |
* | |
* @return resource | |
*/ | |
protected function _getLockFile() | |
{ | |
if ($this->_lockFile === null) { | |
$varDir = Mage::getConfig()->getVarDir('locks'); | |
$file = $varDir . DS . 'stcore_cron.lock'; | |
if (is_file($file)) { | |
$this->_lockFile = fopen($file, 'w'); | |
} else { | |
$this->_lockFile = fopen($file, 'x'); | |
} | |
fwrite($this->_lockFile, date('r')); | |
} | |
return $this->_lockFile; | |
} | |
/** | |
* Lock process without blocking. | |
* This method allow protect multiple process runing and fast lock validation. | |
* | |
* @return Mage_Index_Model_Process | |
*/ | |
public function lock() | |
{ | |
$this->_isLocked = true; | |
flock($this->_getLockFile(), LOCK_EX | LOCK_NB); | |
return $this; | |
} | |
/** | |
* Lock and block process. | |
* If new instance of the process will try validate locking state | |
* script will wait until process will be unlocked | |
* | |
* @return Mage_Index_Model_Process | |
*/ | |
public function lockAndBlock() | |
{ | |
$this->_isLocked = true; | |
flock($this->_getLockFile(), LOCK_EX); | |
return $this; | |
} | |
/** | |
* Unlock process | |
* | |
* @return Mage_Index_Model_Process | |
*/ | |
public function unlock() | |
{ | |
$this->_isLocked = false; | |
flock($this->_getLockFile(), LOCK_UN); | |
return $this; | |
} | |
/** | |
* Check if process is locked | |
* | |
* @return bool | |
*/ | |
public function isLocked() | |
{ | |
if ($this->_isLocked !== null) { | |
return $this->_isLocked; | |
} else { | |
$fp = $this->_getLockFile(); | |
if (flock($fp, LOCK_EX | LOCK_NB)) { | |
flock($fp, LOCK_UN); | |
return false; | |
} | |
return true; | |
} | |
} | |
/** | |
* Close file resource if it was opened | |
*/ | |
public function __destruct() | |
{ | |
if ($this->_lockFile) { | |
fclose($this->_lockFile); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment