diff --git a/src/Lock.php b/src/Lock.php index 2c7099b..3b79ba8 100644 --- a/src/Lock.php +++ b/src/Lock.php @@ -15,6 +15,7 @@ class Lock static private $data = []; static private $dir = null; static private $keyPrefix = null; + static private $defaultLockTimeout = 1.5; /** * @@ -52,6 +53,24 @@ static function setKeyPrefix($prefix) self::$keyPrefix = $prefix; } + /** + * + * @return string + */ + static function getDefaultLockTimeout() + { + return self::$defaultLockTimeout; + } + + /** + * + * @param string $prefix + */ + static function setDefaultLockTimeout($seconds) + { + self::$defaultLockTimeout = $seconds; + } + /** * * @param mixed $key @@ -61,7 +80,7 @@ static function setKeyPrefix($prefix) static public function acquire($key, $options = []) { $keyMD5 = md5(self::$keyPrefix . serialize($key)); - $timeout = isset($options['timeout']) ? (float) $options['timeout'] : 1.5; + $timeout = isset($options['timeout']) ? (float) $options['timeout'] : self::$defaultLockTimeout; $retryInterval = 0.5; $maxRetriesCount = floor($timeout / $retryInterval); $lock = function() use ($keyMD5) { @@ -118,7 +137,11 @@ static public function acquire($key, $options = []) static public function exists($key) { $keyMD5 = md5(self::$keyPrefix . serialize($key)); - $filename = self::getLocksDir() . $keyMD5 . '.lock'; + $dir = self::getLocksDir(); + if (!is_dir($dir)) { + return false; + } + $filename = $dir . $keyMD5 . '.lock'; set_error_handler(function($errno, $errstr) { throw new \Exception($errstr); }); @@ -151,6 +174,9 @@ static public function release($key) $keyMD5 = md5(self::$keyPrefix . serialize($key)); if (!isset(self::$data[$keyMD5])) { throw new \Exception('A lock name "' . $key . '" does not exists in current process!'); + } + $dir = self::getLocksDir(); + if (!is_dir($dir)) { return; } set_error_handler(function($errno, $errstr) { @@ -159,7 +185,7 @@ static public function release($key) try { if (flock(self::$data[$keyMD5], LOCK_UN) && fclose(self::$data[$keyMD5])) { try { - $filename = self::getLocksDir() . $keyMD5 . '.lock'; + $filename = $dir . $keyMD5 . '.lock'; $tempFilename = $filename . '.' . md5(uniqid() . rand(0, 999999)); $renameResult = rename($filename, $tempFilename); if ($renameResult) { diff --git a/tests/LocksTest.php b/tests/LocksTest.php index 2c33147..718496f 100644 --- a/tests/LocksTest.php +++ b/tests/LocksTest.php @@ -48,6 +48,7 @@ public function testRelease() public function testKeyPrefix() { Lock::setKeyPrefix('prefix1'); + $this->assertTrue(Lock::getKeyPrefix() === 'prefix1'); $this->assertTrue(Lock::exists('test1') === false); Lock::acquire('test1'); $this->assertTrue(Lock::exists('test1') === true); @@ -67,6 +68,26 @@ public function testExists() $this->assertTrue(Lock::exists('test3') === false); } + /** + * + */ + public function testTimeout() + { + Lock::setDefaultLockTimeout(2.5); + $this->assertTrue(Lock::getDefaultLockTimeout() === 2.5); + Lock::acquire('test2'); + try { + $time = microtime(true); + Lock::acquire('test2'); + throw new Exception('Should not get here'); + } catch (Exception $e) { + $time = microtime(true) - $time; + $this->assertTrue($e->getMessage() === 'Cannot acquire lock for "test2"'); + $this->assertTrue($time > 2.5); + $this->assertTrue($time < 3); + } + } + /** * */