hyperf-chat/app/Cache/Repository/LockRedis.php

73 lines
1.5 KiB
PHP
Raw Normal View History

2021-05-20 16:53:34 +08:00
<?php
namespace App\Cache\Repository;
use App\Cache\Contracts\LockRedisInterface;
/**
* Redis Lock
*
* @package App\Cache\Repository
*/
2021-05-21 22:56:42 +08:00
class LockRedis extends AbstractRedis implements LockRedisInterface
2021-05-20 16:53:34 +08:00
{
2021-05-21 22:56:42 +08:00
protected $prefix = 'rds-lock';
2021-05-20 16:53:34 +08:00
2021-05-21 22:56:42 +08:00
protected $lockValue = 1;
2021-05-20 16:53:34 +08:00
/**
* 获取是毫秒时间戳
*
* @return int
*/
private function time()
{
return intval(microtime(true) * 1000);
}
/**
* 获取 Redis
*
* @param string $key 锁标识
* @param int $lockTime 过期时间/
* @param int $timeout 获取超时/毫秒
* @return bool
*/
public function lock(string $key, $lockTime = 1, $timeout = 0)
{
$lockName = $this->getCacheKey($key);
$start = $this->time();
do {
$lock = $this->redis()->set($lockName, $this->lockValue, ['nx', 'ex' => $lockTime]);
if ($lock || $timeout === 0) {
break;
}
// 默认 0.1 秒一次取锁
usleep(100000);
} while ($this->time() < $start + $timeout);
return $lock;
}
/**
* 释放 Redis
*
* @param string $key
* @return mixed
*/
public function delete(string $key)
{
$script = <<<LAU
if redis.call("GET", KEYS[1]) == ARGV[1] then
return redis.call("DEL", KEYS[1])
else
return 0
end
LAU;
2021-05-20 22:56:55 +08:00
return $this->redis()->eval($script, [$this->getCacheKey($key), $this->lockValue], 1);
2021-05-20 16:53:34 +08:00
}
}