modify plugin name

This commit is contained in:
2022-02-24 15:24:29 +08:00
parent dbfad195e3
commit 457ae27528
11 changed files with 596 additions and 858 deletions
+3 -3
View File
@@ -441,12 +441,12 @@ if (!function_exists('redis')) {
/** /**
* @return \Kiri\Cache\Redis|Redis * @return \Kiri\Redis\Redis|Redis
* @throws Exception * @throws Exception
*/ */
function redis(): \Kiri\Cache\Redis|Redis function redis(): \Kiri\Redis\Redis|Redis
{ {
return Kiri::getDi()->get(\Kiri\Cache\Redis::class); return Kiri::getDi()->get(\Kiri\Redis\Redis::class);
} }
} }
-141
View File
@@ -1,141 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: whwyy
* Date: 2018/5/2 0002
* Time: 14:51
*/
declare(strict_types=1);
namespace Kiri\Cache;
use JetBrains\PhpStorm\Pure;
use Kiri\Abstracts\Component;
use Swoole\Coroutine\System;
/**
* Class File
* @package Kiri\Cache
*/
class File extends Component implements ICache
{
public string $path;
/**
* @param $key
* @param $val
* @return string|int
*/
public function set($key, $val): string|int
{
if (is_array($val) || is_object($val)) {
$val = swoole_serialize($val);
}
$tmpFile = $this->getCacheKey($key);
if (!$this->exists($tmpFile)) {
touch($tmpFile);
}
return System::writeFile($tmpFile, $val, LOCK_EX);
}
/**
* @param $key
* @param array $hashKeys
* @return array|bool
*/
public function hMGet($key, array $hashKeys): array|bool
{
$hash = $this->get($key);
if (!is_array($hash)) {
return false;
}
$nowHash = [];
foreach ($hashKeys as $hashKey) {
$nowHash[$hashKey] = $hash[$hashKey] ?? null;
}
return $nowHash;
}
/**
* @param $key
* @param array $val
* @return bool|int|string
*/
public function hMSet($key, array $val): bool|int|string
{
$hash = $this->get($key);
if (!is_array($hash)) {
return false;
}
$merge = array_merge($hash, $val);
return $this->set($key, $merge);
}
/**
* @param string $key
* @param string $hashKey
* @return string|int|bool
*/
public function hGet(string $key, string $hashKey): string|int|bool
{
$hash = $this->get($key);
if (!is_array($hash)) {
return false;
}
return $hash[$hashKey] ?? false;
}
/**
* @param $key
* @param $hashKey
* @param $hashValue
* @return bool|int|string
*/
public function hSet($key, $hashKey, $hashValue): bool|int|string
{
$hash = $this->get($key);
if (!is_array($hash)) {
return false;
}
$hash[$hashKey] = $hashValue;
return $this->set($key, $hash);
}
/**
* @param $key
* @return bool
*/
#[Pure] public function exists($key): bool
{
return file_exists($key);
}
/**
* @param $key
* @return mixed|bool
*/
public function get($key): mixed
{
$tmpFile = $this->getCacheKey($key);
if (!$this->exists($tmpFile)) {
return false;
}
$content = file_get_contents($tmpFile);
return swoole_unserialize($content);
}
/**
* @param $key
* @return string
* @throws
*/
private function getCacheKey($key): string
{
return storage($key, 'cache');
}
}
+25 -20
View File
@@ -10,6 +10,8 @@ use Kiri;
use Kiri\Abstracts\Component; use Kiri\Abstracts\Component;
use Kiri\Abstracts\Config; use Kiri\Abstracts\Config;
use Kiri\Context; use Kiri\Context;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Swoole\Error; use Swoole\Error;
use Throwable; use Throwable;
@@ -20,7 +22,19 @@ use Throwable;
class Connection extends Component class Connection extends Component
{ {
use Alias;
private Pool $pool;
/**
* @return void
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function init()
{
$this->pool = $this->getContainer()->get(Pool::class);
}
/** /**
@@ -83,15 +97,15 @@ class Connection extends Component
public function get(mixed $config): ?PDO public function get(mixed $config): ?PDO
{ {
$coroutineName = $config['cds']; $coroutineName = $config['cds'];
//
if (($connection = Context::getContext($coroutineName)) instanceof PDO) { // if (($connection = Context::getContext($coroutineName)) instanceof PDO) {
return $connection; // return $connection;
} // }
$minx = Config::get('databases.pool.min', 1); $minx = Config::get('databases.pool.min', 1);
/** @var PDO $connections */ /** @var PDO $connections */
$connections = $this->getPool()->get($coroutineName, $this->create($coroutineName, $config), $minx); $connections = $this->pool->get($coroutineName, $this->create($coroutineName, $config), $minx);
if (Context::hasContext('begin_' . $coroutineName)) { if (Context::hasContext('begin_' . $coroutineName)) {
$connections->beginTransaction(); $connections->beginTransaction();
} }
@@ -121,7 +135,7 @@ class Connection extends Component
*/ */
public function addItem(string $name, PDO $PDO) public function addItem(string $name, PDO $PDO)
{ {
$this->getPool()->push($name, $PDO); $this->pool->push($name, $PDO);
} }
@@ -132,7 +146,7 @@ class Connection extends Component
*/ */
public function initConnections($name, $max) public function initConnections($name, $max)
{ {
$this->getPool()->initConnections($name, $max); $this->pool->initConnections($name, $max);
} }
@@ -148,7 +162,7 @@ class Connection extends Component
return; return;
} }
$this->getPool()->push($coroutineName, $client); $this->pool->push($coroutineName, $client);
Context::remove($coroutineName); Context::remove($coroutineName);
} }
@@ -169,7 +183,7 @@ class Connection extends Component
*/ */
public function connection_clear($name) public function connection_clear($name)
{ {
$this->getPool()->clean($name); $this->pool->clean($name);
} }
@@ -202,17 +216,8 @@ class Connection extends Component
public function disconnect($coroutineName) public function disconnect($coroutineName)
{ {
Context::remove($coroutineName); Context::remove($coroutineName);
$this->getPool()->clean($coroutineName); $this->pool->clean($coroutineName);
} }
/**
* @return Pool
* @throws Exception
*/
public function getPool(): Pool
{
return Kiri::getDi()->get(Pool::class);
}
} }
+1 -2
View File
@@ -5,11 +5,10 @@ namespace Kiri\Pool;
use Exception; use Exception;
use Kiri\Context;
use Kiri\Abstracts\Component; use Kiri\Abstracts\Component;
use Kiri\Abstracts\Config; use Kiri\Abstracts\Config;
use Kiri\Context;
use Kiri\Exception\ConfigException; use Kiri\Exception\ConfigException;
use Kiri\Pool\Helper\SplQueue;
use Swoole\Coroutine; use Swoole\Coroutine;
use Swoole\Coroutine\Channel; use Swoole\Coroutine\Channel;
@@ -1,28 +1,28 @@
<?php <?php
namespace Kiri\Pool\Helper; namespace Kiri\Pool;
interface QueueInterface interface QueueInterface
{ {
public function isEmpty(): bool; public function isEmpty(): bool;
public function push(mixed $data, float $timeout = -1): bool; public function push(mixed $data, float $timeout = -1): bool;
public function pop(float $timeout = -1): mixed; public function pop(float $timeout = -1): mixed;
public function stats(): array; public function stats(): array;
public function close(): bool; public function close(): bool;
public function length(): int; public function length(): int;
public function isFull(): bool; public function isFull(): bool;
} }
-120
View File
@@ -1,120 +0,0 @@
<?php
declare(strict_types=1);
namespace Kiri\Pool;
use Closure;
use Exception;
use Kiri\Abstracts\Component;
use Kiri\Context;
use Kiri\Exception\ConfigException;
use Kiri;
/**
* Class RedisClient
* @package Kiri\Pool
*/
class Redis extends Component
{
use Alias;
/**
* @param mixed $config
* @param bool $isMaster
* @return mixed
* @throws Exception
*/
public function get(mixed $config, bool $isMaster = false): mixed
{
$coroutineName = $config['host'];
if (Context::hasContext($coroutineName)) {
return Context::getContext($coroutineName);
}
$pool = $config['pool'] ?? ['min' => 1, 'max' => 100];
$clients = $this->getPool()->get($coroutineName, $this->create($coroutineName, $config), $pool['min'] ?? 1);
return Context::setContext($coroutineName, $clients);
}
/**
* @param string $name
* @param mixed $config
* @return Closure
*/
public function create(string $name, mixed $config): Closure
{
return static function () use ($name, $config) {
return Kiri::getDi()->create(\Kiri\Cache\Base\Redis::class, [$config]);
};
}
/**
* @param array $config
* @param bool $isMaster
* @throws ConfigException
* @throws Exception
*/
public function release(array $config, bool $isMaster = false)
{
$coroutineName = $config['host'];
if (!Context::hasContext($coroutineName)) {
return;
}
$this->getPool()->push($coroutineName, Context::getContext($coroutineName));
Context::remove($coroutineName);
}
/**
* @param array $config
* @param bool $isMaster
* @throws Exception
*/
public function destroy(array $config, bool $isMaster = false)
{
$this->getPool()->clean($config['host']);
Context::remove($config['host']);
}
/**
* @param array $config
* @param bool $isMaster
* @throws Exception
*/
public function connection_clear(array $config, bool $isMaster = false)
{
$this->getPool()->clean($config['host']);
}
/**
* @return Pool
* @throws Exception
*/
public function getPool(): Pool
{
return Kiri::getDi()->get(Pool::class);
}
/**
* @param $name
* @param $isMaster
* @param $max
* @throws Exception
*/
public function initConnections($name, $isMaster, $max)
{
$this->getPool()->initConnections($name, $max);
}
}
@@ -1,101 +1,101 @@
<?php <?php
namespace Kiri\Pool\Helper; namespace Kiri\Pool;
use JetBrains\PhpStorm\Pure; use JetBrains\PhpStorm\Pure;
/** /**
* *
*/ */
class SplQueue implements QueueInterface class SplQueue implements QueueInterface
{ {
private \SplQueue $channel; private \SplQueue $channel;
public int $errCode = 0; public int $errCode = 0;
/** /**
* @param int $max * @param int $max
*/ */
#[Pure] public function __construct(public int $max) #[Pure] public function __construct(public int $max)
{ {
$this->channel = new \SplQueue(); $this->channel = new \SplQueue();
} }
/** /**
* @return bool * @return bool
*/ */
public function isEmpty(): bool public function isEmpty(): bool
{ {
// TODO: Implement isEmpty() method. // TODO: Implement isEmpty() method.
return $this->channel->count() < 1; return $this->channel->count() < 1;
} }
/** /**
* @param mixed $data * @param mixed $data
* @param float $timeout * @param float $timeout
* @return bool * @return bool
*/ */
public function push(mixed $data, float $timeout = -1): bool public function push(mixed $data, float $timeout = -1): bool
{ {
// TODO: Implement push() method. // TODO: Implement push() method.
$this->channel->enqueue($data); $this->channel->enqueue($data);
return true; return true;
} }
/** /**
* @param float $timeout * @param float $timeout
* @return mixed * @return mixed
*/ */
public function pop(float $timeout = -1): mixed public function pop(float $timeout = -1): mixed
{ {
// TODO: Implement pop() method. // TODO: Implement pop() method.
return $this->channel->dequeue(); return $this->channel->dequeue();
} }
/** /**
* @return array * @return array
*/ */
public function stats(): array public function stats(): array
{ {
// TODO: Implement stats() method. // TODO: Implement stats() method.
return []; return [];
} }
/** /**
* @return bool * @return bool
*/ */
public function close(): bool public function close(): bool
{ {
// TODO: Implement close() method. // TODO: Implement close() method.
return false; return false;
} }
/** /**
* @return int * @return int
*/ */
public function length(): int public function length(): int
{ {
// TODO: Implement length() method. // TODO: Implement length() method.
return $this->channel->count(); return $this->channel->count();
} }
/** /**
* @return bool * @return bool
*/ */
public function isFull(): bool public function isFull(): bool
{ {
// TODO: Implement isFull() method. // TODO: Implement isFull() method.
return $this->channel->count() >= $this->max; return $this->channel->count() >= $this->max;
} }
} }
@@ -1,65 +1,65 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: whwyy * User: whwyy
* Date: 2018/11/8 0008 * Date: 2018/11/8 0008
* Time: 16:35 * Time: 16:35
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Cache; namespace Kiri\Redis;
/** /**
* Interface ICache * Interface ICache
* @package Kiri\Cache * @package Kiri\Cache
*/ */
interface ICache interface CacheInterface
{ {
/** /**
* @param $key * @param $key
* @param $val * @param $val
* @return string|int * @return string|int
*/ */
public function set($key, $val): string|int; public function set($key, $val): string|int;
/** /**
* @param $key * @param $key
* @return string|int|bool * @return string|int|bool
*/ */
public function get($key): mixed; public function get($key): mixed;
/** /**
* @param $key * @param $key
* @param array $hashKeys * @param array $hashKeys
* @return array|bool|null * @return array|bool|null
*/ */
public function hMGet($key, array $hashKeys): array|bool|null; public function hMGet($key, array $hashKeys): array|bool|null;
/** /**
* @param $key * @param $key
* @param array $val * @param array $val
* @return mixed * @return mixed
*/ */
public function hMSet($key, array $val): mixed; public function hMSet($key, array $val): mixed;
/** /**
* @param string $key * @param string $key
* @param string $hashKey * @param string $hashKey
* @return string|int|bool * @return string|int|bool
*/ */
public function hGet(string $key, string $hashKey): string|int|bool; public function hGet(string $key, string $hashKey): string|int|bool;
/** /**
* @param $key * @param $key
* @param $hashKey * @param $hashKey
* @param $hashValue * @param $hashValue
* @return mixed * @return mixed
*/ */
public function hSet($key, $hashKey, $hashValue): mixed; public function hSet($key, $hashKey, $hashValue): mixed;
/** /**
* @param $key * @param $key
* @return bool * @return bool
*/ */
public function exists($key): bool; public function exists($key): bool;
} }
@@ -1,186 +1,171 @@
<?php <?php
namespace Kiri\Cache\Base; namespace Kiri\Redis;
use Exception; use Exception;
use Kiri\Abstracts\Logger; use Kiri;
use Kiri\Events\EventProvider; use Kiri\Abstracts\Logger;
use Kiri\Exception\RedisConnectException; use Kiri\Exception\RedisConnectException;
use Kiri; use Kiri\Pool\StopHeartbeatCheck;
use Kiri\Pool\StopHeartbeatCheck; use Kiri\Server\Events\OnWorkerExit;
use Kiri\Server\Events\OnWorkerExit; use RedisException;
use RedisException; use Swoole\Timer;
use Swoole\Timer; use function error;
/** /**
* *
*/ */
class Redis implements StopHeartbeatCheck class Helper implements StopHeartbeatCheck
{ {
const DB_ERROR_MESSAGE = 'The system is busy, please try again later.'; private ?\Redis $pdo = null;
public string $host;
private ?\Redis $pdo = null;
public int $port;
public string $host;
public int $database = 0;
public int $port;
public string $auth = '';
public int $database = 0;
public string $prefix = '';
public string $auth = '';
public int $timeout = 30;
public string $prefix = '';
public int $read_timeout = 30;
public int $timeout = 30;
public array $pool = [];
public int $read_timeout = 30;
private int $_timer = -1;
public array $pool = [];
private int $_last = 0;
private int $_timer = -1;
private int $_last = 0;
/**
* @param array $config
*/
/** public function __construct(array $config)
* @param array $config {
*/ $this->host = $config['host'];
public function __construct(array $config) $this->port = $config['port'];
{ $this->database = $config['databases'];
$this->host = $config['host']; $this->auth = $config['auth'];
$this->port = $config['port']; $this->prefix = $config['prefix'];
$this->database = $config['databases']; $this->timeout = $config['timeout'];
$this->auth = $config['auth']; $this->read_timeout = $config['read_timeout'];
$this->prefix = $config['prefix']; $this->pool = $config['pool'];
$this->timeout = $config['timeout']; }
$this->read_timeout = $config['read_timeout'];
$this->pool = $config['pool'];
} public function init()
{
$this->heartbeat_check();
public function init() }
{
$this->heartbeat_check();
} /**
*
*/
public function heartbeat_check(): void
{
/**
* @param Kiri\Server\Events\OnWorkerExit $exit if ($this->_timer === -1) {
* @return void $this->_timer = Timer::tick(1000, fn() => $this->waite());
*/ }
public function onWorkerExit(OnWorkerExit $exit) }
{
$this->stopHeartbeatCheck();
} /**
* @throws Exception
*/
/** private function waite(): void
* {
*/ try {
public function heartbeat_check(): void if ($this->_timer === -1) {
{ Kiri::getDi()->get(Logger::class)->critical('timer end');
$this->stopHeartbeatCheck();
if ($this->_timer === -1) { }
$this->_timer = Timer::tick(1000, fn() => $this->waite()); if (time() - $this->_last > intval($this->pool['tick'] ?? 60)) {
} $this->stopHeartbeatCheck();
}
$this->pdo = null;
}
/** } catch (\Throwable $throwable) {
* @throws Exception error($throwable);
*/ }
private function waite(): void }
{
try {
if ($this->_timer === -1) { /**
Kiri::getDi()->get(Logger::class)->critical('timer end'); *
$this->stopHeartbeatCheck(); */
} public function stopHeartbeatCheck(): void
if (time() - $this->_last > intval($this->pool['tick'] ?? 60)) { {
$this->stopHeartbeatCheck(); if ($this->_timer > -1) {
Timer::clear($this->_timer);
$this->pdo = null; }
} $this->_timer = -1;
} catch (\Throwable $throwable) { }
error($throwable);
}
} /**
* @param string $name
* @param array $arguments
/** * @return mixed
* * @throws RedisConnectException|RedisException
*/ */
public function stopHeartbeatCheck(): void public function __call(string $name, array $arguments)
{ {
if ($this->_timer > -1) { if (!method_exists($this, $name)) {
Timer::clear($this->_timer); return $this->_pdo()->{$name}(...$arguments);
} }
$this->_timer = -1; return $this->{$name}(...$arguments);
} }
/** /**
* @param string $name * @return \Redis
* @param array $arguments * @throws RedisConnectException
* @return mixed * @throws RedisException
* @throws RedisConnectException|RedisException */
*/ public function _pdo(): \Redis
public function __call(string $name, array $arguments) {
{ if ($this->_timer === -1) {
if (!method_exists($this, $name)) { $this->heartbeat_check();
return $this->_pdo()->{$name}(...$arguments); }
} $this->_last = time();
return $this->{$name}(...$arguments); if (!($this->pdo instanceof \Redis) || !$this->pdo->ping('isOk')) {
} $this->pdo = $this->newClient();
}
return $this->pdo;
/** }
* @return \Redis
* @throws RedisConnectException
* @throws RedisException /**
*/ * @return \Redis
public function _pdo(): \Redis * @throws RedisConnectException
{ */
if ($this->_timer === -1) { private function newClient(): \Redis
$this->heartbeat_check(); {
} $redis = new \Redis();
$this->_last = time(); if (!$redis->connect($this->host, $this->port, $this->timeout)) {
if (!($this->pdo instanceof \Redis) || !$this->pdo->ping('isOk')) { throw new RedisConnectException(sprintf('The Redis Connect %s::%d Fail.', $this->host, $this->port));
$this->pdo = $this->newClient(); }
} if (!empty($this->auth) && !$redis->auth($this->auth)) {
return $this->pdo; throw new RedisConnectException(sprintf('Redis Error: %s, Host %s, Auth %s', $redis->getLastError(), $this->host, $this->auth));
} }
if ($this->read_timeout < 0) {
$this->read_timeout = 0;
/** }
* @return \Redis $redis->select($this->database);
* @throws RedisConnectException if ($this->read_timeout > 0) {
*/ $redis->setOption(\Redis::OPT_READ_TIMEOUT, $this->read_timeout);
private function newClient(): \Redis }
{ $redis->setOption(\Redis::OPT_PREFIX, $this->prefix);
$redis = new \Redis(); return $redis;
if (!$redis->connect($this->host, $this->port, $this->timeout)) {
throw new RedisConnectException(sprintf('The Redis Connect %s::%d Fail.', $this->host, $this->port)); }
}
if (!empty($this->auth) && !$redis->auth($this->auth)) { }
throw new RedisConnectException(sprintf('Redis Error: %s, Host %s, Auth %s', $redis->getLastError(), $this->host, $this->auth));
}
if ($this->read_timeout < 0) {
$this->read_timeout = 0;
}
$redis->select($this->database);
if ($this->read_timeout > 0) {
$redis->setOption(\Redis::OPT_READ_TIMEOUT, $this->read_timeout);
}
$redis->setOption(\Redis::OPT_PREFIX, $this->prefix);
return $redis;
}
}
@@ -1,191 +1,201 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: whwyy * User: whwyy
* Date: 2018/4/27 0027 * Date: 2018/4/27 0027
* Time: 11:00 * Time: 11:00
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Cache; namespace Kiri\Redis;
use Exception; use Exception;
use Kiri\Abstracts\Component; use Kiri;
use Kiri\Abstracts\Config; use Kiri\Abstracts\Component;
use Kiri\Core\Json; use Kiri\Abstracts\Config;
use Kiri\Events\EventProvider; use Kiri\Core\Json;
use Kiri\Exception\ConfigException; use Kiri\Exception\ConfigException;
use Kiri; use Kiri\Pool\Pool;
use Kiri\Pool\Redis as PoolRedis; use Kiri\Server\Events\OnWorkerExit;
use Kiri\Annotation\Inject; use Psr\Container\ContainerExceptionInterface;
use Kiri\Server\Events\OnWorkerExit; use Psr\Container\NotFoundExceptionInterface;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface; /**
use Swoole\Timer; * Class Redis
* @package Kiri\Cache
/** * @mixin \Redis
* Class Redis */
* @package Kiri\Cache class Redis extends Component
* @mixin \Redis {
*/
class Redis extends Component
{ const REDIS_OPTION_HOST = 'host';
const REDIS_OPTION_PORT = 'port';
const REDIS_OPTION_PREFIX = 'prefix';
const REDIS_OPTION_HOST = 'host'; const REDIS_OPTION_AUTH = 'auth';
const REDIS_OPTION_PORT = 'port'; const REDIS_OPTION_DATABASES = 'databases';
const REDIS_OPTION_PREFIX = 'prefix'; const REDIS_OPTION_TIMEOUT = 'timeout';
const REDIS_OPTION_AUTH = 'auth'; const REDIS_OPTION_POOL = 'pool';
const REDIS_OPTION_DATABASES = 'databases'; const REDIS_OPTION_POOL_TICK = 'tick';
const REDIS_OPTION_TIMEOUT = 'timeout'; const REDIS_OPTION_POOL_MIN = 'min';
const REDIS_OPTION_POOL = 'pool'; const REDIS_OPTION_POOL_MAX = 'max';
const REDIS_OPTION_POOL_TICK = 'tick';
const REDIS_OPTION_POOL_MIN = 'min';
const REDIS_OPTION_POOL_MAX = 'max'; private Kiri\Pool\Pool $pool;
/** /**
* @return void * @return void
* @throws ConfigException * @throws ConfigException
* @throws ContainerExceptionInterface * @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface * @throws NotFoundExceptionInterface
* @throws Exception * @throws Exception
*/ */
public function init() public function init()
{ {
$connections = Kiri::getDi()->get(PoolRedis::class); $this->pool = Kiri::getDi()->get(Pool::class);
$config = $this->get_config(); $config = $this->get_config();
$length = Config::get('cache.redis.pool.max', 10); $length = Config::get('cache.redis.pool.max', 10);
$this->getEventProvider()->on(OnWorkerExit::class, [$this, 'destroy'], 0); $this->getEventProvider()->on(OnWorkerExit::class, [$this, 'destroy'], 0);
$connections->initConnections('Redis:' . $config['host'], true, $length); $this->pool->initConnections($config['host'], $length);
} }
/** /**
* @param $name * @param $name
* @param $arguments * @param $arguments
* @return mixed * @return mixed
* @throws * @throws
*/ */
public function __call($name, $arguments): mixed public function __call($name, $arguments): mixed
{ {
$time = microtime(true); $time = microtime(true);
if (method_exists($this, $name)) { if (method_exists($this, $name)) {
$data = $this->{$name}(...$arguments); $data = $this->{$name}(...$arguments);
} else { } else {
$data = $this->proxy($name, $arguments); $data = $this->proxy($name, $arguments);
} }
if (microtime(true) - $time >= 0.02) { if (microtime(true) - $time >= 0.02) {
$this->logger->warning('Redis:' . Json::encode([$name, $arguments]) . (microtime(true) - $time)); $this->logger->warning('Redis:' . Json::encode([$name, $arguments]) . (microtime(true) - $time));
} }
return $data; return $data;
} }
/** /**
* @param $key * @param $key
* @param int $timeout * @param int $timeout
* @return bool * @return bool
*/ */
public function waite($key, int $timeout = 5): bool public function waite($key, int $timeout = 5): bool
{ {
$time = time(); $time = time();
while (!$this->setNx($key, 1)) { while (!$this->setNx($key, 1)) {
if (time()- $time >= $timeout) { if (time() - $time >= $timeout) {
return FALSE; return FALSE;
} }
usleep(1000); usleep(1000);
} }
$this->expire($key, $timeout); $this->expire($key, $timeout);
return TRUE; return TRUE;
} }
/** /**
* @param $key * @param $key
* @param int $timeout * @param int $timeout
* @return bool|int * @return bool|int
* @throws Exception * @throws Exception
*/ */
public function lock($key, int $timeout = 5): bool|int public function lock($key, int $timeout = 5): bool|int
{ {
$script = <<<SCRIPT $script = <<<SCRIPT
local _nx = redis.call('setnx',KEYS[1], ARGV[1]) local _nx = redis.call('setnx',KEYS[1], ARGV[1])
if (_nx ~= 0) then if (_nx ~= 0) then
redis.call('expire',KEYS[1], ARGV[1]) redis.call('expire',KEYS[1], ARGV[1])
return 1 return 1
end end
return 0 return 0
SCRIPT; SCRIPT;
return $this->eval($script, ['{lock}:' . $key, $timeout], 1); return $this->eval($script, ['{lock}:' . $key, $timeout], 1);
} }
/** /**
* @param $key * @param $key
* @return int * @return int
* @throws Exception * @throws Exception
*/ */
public function unlock($key): int public function unlock($key): int
{ {
return $this->del('{lock}:' . $key); return $this->del('{lock}:' . $key);
} }
/** /**
* @throws ConfigException * @throws ConfigException
* @throws Exception * @throws Exception
*/ */
public function release() public function release()
{ {
$connections = Kiri::getDi()->get(PoolRedis::class); $this->pool->clean($this->get_config()['host']);
$connections->release($this->get_config(), true); }
}
/**
/** * 销毁连接池
* 销毁连接池 * @throws ConfigException
* @throws ConfigException * @throws Exception
* @throws Exception */
*/ public function destroy()
public function destroy() {
{ $this->pool->clean($this->get_config()['host']);
$connections = Kiri::getDi()->get(PoolRedis::class); }
$connections->connection_clear($this->get_config(), true);
} /**
* @param $name
/** * @param $arguments
* @param $name * @return mixed
* @param $arguments * @throws ConfigException
* @return mixed * @throws Exception
* @throws ConfigException */
* @throws Exception public function proxy($name, $arguments): mixed
*/ {
public function proxy($name, $arguments): mixed $client = $this->getClient();
{ try {
$connections = Kiri::getDi()->get(PoolRedis::class); $response = $client->{$name}(...$arguments);
} catch (\Throwable $throwable) {
$config = $this->get_config(); $response = $this->logger->addError($throwable->getMessage());
} finally {
$client = $connections->get($config, true); $this->pool->push($this->get_config()['host'], $client);
if (!($client instanceof Base\Redis)) { }
throw new Exception('Redis connections more.'); return $response;
} }
$response = $client->{$name}(...$arguments);
$this->release();
return $response; /**
} * @return Helper
* @throws ConfigException
/** */
* @return array private function getClient(): Helper
* @throws ConfigException {
*/ $config = $this->get_config();
public function get_config(): array return $this->pool->get($config['host'], static function () use ($config) {
{ return new Helper($config);
return Config::get('cache.redis', null, true); }, 10);
} }
}
/**
* @return array
* @throws ConfigException
*/
public function get_config(): array
{
return Config::get('cache.redis', null, true);
}
}
+1 -1
View File
@@ -12,7 +12,7 @@ namespace Gii;
use Database\Connection; use Database\Connection;
use Database\Db; use Database\Db;
use Exception; use Exception;
use Kiri\Cache\Redis; use Kiri\Redis\Redis;
use Kiri; use Kiri;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;