diff --git a/extensions/mutex/yii/mutex/db/Mutex.php b/extensions/mutex/yii/mutex/DbMutex.php similarity index 71% rename from extensions/mutex/yii/mutex/db/Mutex.php rename to extensions/mutex/yii/mutex/DbMutex.php index 17dd68a..3699c36 100644 --- a/extensions/mutex/yii/mutex/db/Mutex.php +++ b/extensions/mutex/yii/mutex/DbMutex.php @@ -5,7 +5,7 @@ * @license http://www.yiiframework.com/license/ */ -namespace yii\mutex\db; +namespace yii\mutex; use Yii; use yii\db\Connection; @@ -15,7 +15,7 @@ use yii\base\InvalidConfigException; * @author resurtm * @since 2.0 */ -abstract class Mutex extends \yii\mutex\Mutex +abstract class DbMutex extends Mutex { /** * @var Connection|string the DB connection object or the application component ID of the DB connection. @@ -38,14 +38,4 @@ abstract class Mutex extends \yii\mutex\Mutex throw new InvalidConfigException('Mutex::db must be either a DB connection instance or the application component ID of a DB connection.'); } } - - /** - * This method should be extended by concrete mutex implementations. Returns whether current mutex - * implementation can be used in a distributed environment. - * @return boolean whether current mutex implementation can be used in a distributed environment. - */ - public function getIsDistributed() - { - return true; - } } diff --git a/extensions/mutex/yii/mutex/unix/Mutex.php b/extensions/mutex/yii/mutex/FileMutex.php similarity index 61% rename from extensions/mutex/yii/mutex/unix/Mutex.php rename to extensions/mutex/yii/mutex/FileMutex.php index ca18a49..4a949d0 100644 --- a/extensions/mutex/yii/mutex/unix/Mutex.php +++ b/extensions/mutex/yii/mutex/FileMutex.php @@ -5,7 +5,7 @@ * @license http://www.yiiframework.com/license/ */ -namespace yii\mutex\unix; +namespace yii\mutex; use Yii; use yii\base\InvalidConfigException; @@ -14,9 +14,14 @@ use yii\base\InvalidConfigException; * @author resurtm * @since 2.0 */ -class Mutex extends \yii\mutex\Mutex +class FileMutex extends Mutex { /** + * @var string the directory to store mutex files. You may use path alias here. + * If not set, it will use the "mutex" subdirectory under the application runtime path. + */ + public $mutexPath = '@runtime/mutex'; + /** * @var resource[] stores all opened lock files. Keys are lock names and values are file handles. */ private $_files = array(); @@ -30,7 +35,11 @@ class Mutex extends \yii\mutex\Mutex public function init() { if (stripos(php_uname('s'), 'win') === 0) { - throw new InvalidConfigException(''); + throw new InvalidConfigException('FileMutex does not have MS Windows operating system support.'); + } + $this->mutexPath = Yii::getAlias($this->mutexPath); + if (!is_dir($this->mutexPath)) { + mkdir($this->mutexPath, 0777, true); } } @@ -40,9 +49,9 @@ class Mutex extends \yii\mutex\Mutex * @param integer $timeout to wait for lock to become released. * @return boolean acquiring result. */ - protected function acquire($name, $timeout = 0) + protected function acquireLock($name, $timeout = 0) { - $file = fopen(Yii::$app->getRuntimePath() . '/mutex.' . md5($name) . '.lock', 'w+'); + $file = fopen($this->mutexPath . '/' . md5($name) . '.lock', 'w+'); if ($file === false) { return false; } @@ -64,7 +73,7 @@ class Mutex extends \yii\mutex\Mutex * @param string $name of the lock to be released. * @return boolean release result. */ - protected function release($name) + protected function releaseLock($name) { if (!isset($this->_files[$name]) || !flock($this->_files[$name], LOCK_UN)) { return false; @@ -74,26 +83,4 @@ class Mutex extends \yii\mutex\Mutex return true; } } - - /** - * This method may optionally be extended by concrete mutex implementations. Checks whether lock has been - * already acquired by given name. - * @param string $name of the lock to be released. - * @return null|boolean whether lock has been already acquired. Returns `null` in case this feature - * is not supported by concrete mutex implementation. - */ - protected function getIsAcquired($name) - { - return false; - } - - /** - * This method should be extended by concrete mutex implementations. Returns whether current mutex - * implementation can be used in a distributed environment. - * @return boolean whether current mutex implementation can be used in a distributed environment. - */ - public function getIsDistributed() - { - return false; - } } diff --git a/extensions/mutex/yii/mutex/db/mssql/Mutex.php b/extensions/mutex/yii/mutex/MssqlMutex.php similarity index 77% rename from extensions/mutex/yii/mutex/db/mssql/Mutex.php rename to extensions/mutex/yii/mutex/MssqlMutex.php index 374100a..d267699 100644 --- a/extensions/mutex/yii/mutex/db/mssql/Mutex.php +++ b/extensions/mutex/yii/mutex/MssqlMutex.php @@ -5,7 +5,7 @@ * @license http://www.yiiframework.com/license/ */ -namespace yii\mutex\db\mssql; +namespace yii\mutex; use Yii; use yii\base\InvalidConfigException; @@ -14,7 +14,7 @@ use yii\base\InvalidConfigException; * @author resurtm * @since 2.0 */ -class Mutex extends \yii\mutex\db\Mutex +class MssqlMutex extends Mutex { /** * Initializes Microsoft SQL Server specific mutex component implementation. @@ -25,7 +25,7 @@ class Mutex extends \yii\mutex\db\Mutex parent::init(); $driverName = $this->db->driverName; if ($driverName !== 'sqlsrv' && $driverName !== 'dblib' && $driverName !== 'mssql') { - throw new InvalidConfigException(''); + throw new InvalidConfigException('In order to use MssqlMutex connection must be configured to use MS SQL Server database.'); } } @@ -34,10 +34,10 @@ class Mutex extends \yii\mutex\db\Mutex * @param string $name of the lock to be acquired. * @param integer $timeout to wait for lock to become released. * @return boolean acquiring result. - * @throws \BadMethodCallException + * @throws \BadMethodCallException not implemented yet. * @see http://msdn.microsoft.com/en-us/library/ms189823.aspx */ - protected function acquire($name, $timeout = 0) + protected function acquireLock($name, $timeout = 0) { throw new \BadMethodCallException('Not implemented yet.'); } @@ -46,10 +46,10 @@ class Mutex extends \yii\mutex\db\Mutex * This method should be extended by concrete mutex implementations. Releases lock by given name. * @param string $name of the lock to be released. * @return boolean release result. - * @throws \BadMethodCallException + * @throws \BadMethodCallException not implemented yet. * @see http://msdn.microsoft.com/en-us/library/ms178602.aspx */ - protected function release($name) + protected function releaseLock($name) { throw new \BadMethodCallException('Not implemented yet.'); } diff --git a/extensions/mutex/yii/mutex/Mutex.php b/extensions/mutex/yii/mutex/Mutex.php index 9f47501..297abaf 100644 --- a/extensions/mutex/yii/mutex/Mutex.php +++ b/extensions/mutex/yii/mutex/Mutex.php @@ -18,7 +18,8 @@ abstract class Mutex extends Component { /** * @var boolean whether all locks acquired in this process (i.e. local locks) must be released automagically - * before finishing script execution. Defaults to true. Setting this property to true + * before finishing script execution. Defaults to true. Setting this property to true means that all locks + * acquire in this process must be released in any case (regardless any kind of errors or exceptions). */ public $autoRelease = true; /** @@ -33,14 +34,13 @@ abstract class Mutex extends Component public function init() { if ($this->autoRelease) { - $references = new stdClass(); - $references->mutex = $this; - $references->locks = &$this->_locks; - register_shutdown_function(function ($refs) { - foreach ($refs->locks as $lock) { - $refs->mutex->release($lock); + $mutex = $this; + $locks = &$this->_locks; + register_shutdown_function(function () use ($mutex, &$locks) { + foreach ($locks as $lock) { + $mutex->release($lock); } - }, $references); + }); } } @@ -50,9 +50,9 @@ abstract class Mutex extends Component * false immediately in case lock was already acquired. * @return boolean lock acquiring result. */ - public function acquireLock($name, $timeout = 0) + public function acquire($name, $timeout = 0) { - if ($this->acquire($name, $timeout)) { + if ($this->acquireLock($name, $timeout)) { $this->_locks[] = $name; return true; } else { @@ -65,9 +65,9 @@ abstract class Mutex extends Component * @param string $name of the lock to be released. This lock must be already created. * @return boolean lock release result: false in case named lock was not found.. */ - public function releaseLock($name) + public function release($name) { - if ($this->release($name)) { + if ($this->releaseLock($name)) { $index = array_search($name, $this->_locks); if ($index !== false) { unset($this->_locks[$index]); @@ -79,62 +79,17 @@ abstract class Mutex extends Component } /** - * Checks whether named lock was already opened. - * @param string $name of the lock to be checked. This lock must be already created. - * @return boolean|null whether named lock was already opened. Returns `null` value in case concrete - * mutex implementation does not support this operation. - */ - public function getIsLockAcquired($name) - { - if (in_array($name, $this->_locks)) { - return true; - } else { - return $this->getIsAcquired($name); - } - } - - /** - * Checks whether given lock is local. In other words local lock means that it was opened in the current - * PHP process. - * @param string $name of the lock to be checked. This lock must be already created. - * @return boolean whether named lock was locally acquired. - */ - public function getIsLockLocal($name) - { - return in_array($name, $this->_locks); - } - - /** * This method should be extended by concrete mutex implementations. Acquires lock by given name. * @param string $name of the lock to be acquired. * @param integer $timeout to wait for lock to become released. * @return boolean acquiring result. */ - abstract protected function acquire($name, $timeout = 0); + abstract protected function acquireLock($name, $timeout = 0); /** * This method should be extended by concrete mutex implementations. Releases lock by given name. * @param string $name of the lock to be released. * @return boolean release result. */ - abstract protected function release($name); - - /** - * This method may optionally be extended by concrete mutex implementations. Checks whether lock has been - * already acquired by given name. - * @param string $name of the lock to be released. - * @return null|boolean whether lock has been already acquired. Returns `null` in case this feature - * is not supported by concrete mutex implementation. - */ - protected function getIsAcquired($name) - { - return null; - } - - /** - * This method should be extended by concrete mutex implementations. Returns whether current mutex - * implementation can be used in a distributed environment. - * @return boolean whether current mutex implementation can be used in a distributed environment. - */ - abstract public function getIsDistributed(); + abstract protected function releaseLock($name); } diff --git a/extensions/mutex/yii/mutex/db/mysql/Mutex.php b/extensions/mutex/yii/mutex/MysqlMutex.php similarity index 63% rename from extensions/mutex/yii/mutex/db/mysql/Mutex.php rename to extensions/mutex/yii/mutex/MysqlMutex.php index 7153d38..b04427a 100644 --- a/extensions/mutex/yii/mutex/db/mysql/Mutex.php +++ b/extensions/mutex/yii/mutex/MysqlMutex.php @@ -5,7 +5,7 @@ * @license http://www.yiiframework.com/license/ */ -namespace yii\mutex\db\mysql; +namespace yii\mutex; use Yii; use yii\base\InvalidConfigException; @@ -14,7 +14,7 @@ use yii\base\InvalidConfigException; * @author resurtm * @since 2.0 */ -class Mutex extends \yii\mutex\db\Mutex +class MysqlMutex extends Mutex { /** * Initializes MySQL specific mutex component implementation. @@ -24,7 +24,7 @@ class Mutex extends \yii\mutex\db\Mutex { parent::init(); if ($this->db->driverName !== 'mysql') { - throw new InvalidConfigException(''); + throw new InvalidConfigException('In order to use MysqlMutex connection must be configured to use MySQL database.'); } } @@ -35,7 +35,7 @@ class Mutex extends \yii\mutex\db\Mutex * @return boolean acquiring result. * @see http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_get-lock */ - protected function acquire($name, $timeout = 0) + protected function acquireLock($name, $timeout = 0) { return (boolean)$this->db ->createCommand('SELECT GET_LOCK(:name, :timeout)', array(':name' => $name, ':timeout' => $timeout)) @@ -48,25 +48,10 @@ class Mutex extends \yii\mutex\db\Mutex * @return boolean release result. * @see http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_release-lock */ - protected function release($name) + protected function releaseLock($name) { return (boolean)$this->db ->createCommand('SELECT RELEASE_LOCK(:name)', array(':name' => $name)) ->queryScalar(); } - - /** - * This method may optionally be extended by concrete mutex implementations. Checks whether lock has been - * already acquired by given name. - * @param string $name of the lock to be released. - * @return null|boolean whether lock has been already acquired. Returns `null` in case this feature - * is not supported by concrete mutex implementation. - * @see http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_is-free-lock - */ - protected function getIsAcquired($name) - { - return (boolean)$this->db - ->createCommand('SELECT IS_FREE_LOCK(:name)', array(':name' => $name)) - ->queryScalar(); - } } diff --git a/extensions/mutex/yii/mutex/cache/Mutex.php b/extensions/mutex/yii/mutex/cache/Mutex.php deleted file mode 100644 index 73e277b..0000000 --- a/extensions/mutex/yii/mutex/cache/Mutex.php +++ /dev/null @@ -1,89 +0,0 @@ - - * @since 2.0 - */ -class Mutex extends \yii\mutex\Mutex -{ - /** - * @var Cache|string the cache object or the application component ID of the cache object. - * The messages data will be cached using this cache object. Note, this property has meaning only - * in case [[cachingDuration]] set to non-zero value. - * After the Mutex object is created, if you want to change this property, you should only assign - * it with a cache object. - */ - public $cache = 'cache'; - - - /** - * Initializes the DbMessageSource component. Configured [[cache]] component will be initialized. - * @throws InvalidConfigException if [[cache]] is invalid. - */ - public function init() - { - parent::init(); - if (is_string($this->cache)) { - $this->cache = Yii::$app->getComponent($this->cache); - } - if (!$this->cache instanceof Cache) { - throw new InvalidConfigException('Mutex::cache must be either a cache object or the application component ID of the cache object.'); - } - } - - /** - * This method should be extended by concrete mutex implementations. Acquires lock by given name. - * @param string $name of the lock to be acquired. - * @param integer $timeout to wait for lock to become released. - * @return boolean acquiring result. - */ - protected function acquire($name, $timeout = 0) - { - - } - - /** - * This method should be extended by concrete mutex implementations. Releases lock by given name. - * @param string $name of the lock to be released. - * @return boolean release result. - */ - protected function release($name) - { - return $this->cache->delete("mutex.{$name}"); - } - - /** - * This method may optionally be extended by concrete mutex implementations. Checks whether lock has been - * already acquired by given name. - * @param string $name of the lock to be released. - * @return null|boolean whether lock has been already acquired. Returns `null` in case this feature - * is not supported by concrete mutex implementation. - */ - protected function getIsAcquired($name) - { - - } - - /** - * This method should be extended by concrete mutex implementations. Returns whether current mutex - * implementation can be used in a distributed environment. - * @return boolean whether current mutex implementation can be used in a distributed environment. - */ - public function getIsDistributed() - { - return $this->cache instanceof DbCache || $this->cache instanceof MemCache; - } -}