From 0d848dc5f117f1e721e3806930528f5eaac0416a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mr=C2=B7x?= Date: Mon, 4 Jan 2021 16:53:29 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B9=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- System/Pool/Connection.php | 39 ++++++++++---------- System/Pool/Redis.php | 74 ++++++++++++++++++++++++-------------- 2 files changed, 68 insertions(+), 45 deletions(-) diff --git a/System/Pool/Connection.php b/System/Pool/Connection.php index 30d2d918..8ad44182 100644 --- a/System/Pool/Connection.php +++ b/System/Pool/Connection.php @@ -36,20 +36,14 @@ class Connection extends Pool */ public function Heartbeat_detection($timer) { - try { - $this->creates = $timer; - if ($this->lastTime == 0) { - return; - } - if ($this->lastTime + 600 < time()) { - $this->flush(0); - } else if ($this->lastTime + 300 < time()) { - $this->flush(2); - } - } catch (\Throwable $exception) { - var_dump($exception->getMessage()); - var_dump($exception->getFile()); - var_dump($exception->getLine()); + $this->creates = $timer; + if ($this->lastTime == 0) { + return; + } + if ($this->lastTime + 600 < time()) { + $this->flush(0); + } else if ($this->lastTime + 300 < time()) { + $this->flush(2); } } @@ -242,7 +236,9 @@ class Connection extends Pool */ private function nowClient($coroutineName, $config): PDO { - $client = $this->createConnect($coroutineName, ...$this->parseConfig($config)); + + $this->createConnect($coroutineName, ...$this->parseConfig($config)); + [$time, $client] = $this->get($coroutineName); if ($number = Context::getContext('begin_' . $coroutineName, Coroutine::getCid())) { $number > 0 && $client->beginTransaction(); } @@ -361,12 +357,15 @@ class Connection extends Pool * @param $username * @param $password * @param string $charset - * @return PDO * @throws Exception */ - public function createConnect($coroutineName, $cds, $username, $password, $charset = 'utf8mb4'): PDO + public function createConnect($coroutineName, $cds, $username, $password, $charset = 'utf8mb4'): void { try { + if (Context::hasContext('at_create_db')) { + return; + } + Context::setContext('at_create_db',1); $link = new PDO($cds, $username, $password, [ PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_CASE => PDO::CASE_NATURAL, @@ -380,13 +379,15 @@ class Connection extends Pool } $this->success('create db client -> ' . $cds . ':' . $this->hasCreate[$coroutineName] . ':' . $this->size($coroutineName)); $this->incr($coroutineName); - return $link; + $this->push($coroutineName, $link); } catch (\Throwable $exception) { $this->addError($cds . ' -> ' . $exception->getMessage()); if ($exception->getCode() === 2006) { - return $this->createConnect($coroutineName, $cds, $username, $password, $charset); + $this->createConnect($coroutineName, $cds, $username, $password, $charset); } throw new Exception($exception->getMessage()); + } finally { + Context::deleteId('at_create_db'); } } diff --git a/System/Pool/Redis.php b/System/Pool/Redis.php index 4d484cfa..a9a60714 100644 --- a/System/Pool/Redis.php +++ b/System/Pool/Redis.php @@ -19,6 +19,10 @@ use Exception; class Redis extends Pool { + + private int $_create = 0; + + /** * @param $value */ @@ -32,7 +36,6 @@ class Redis extends Pool * @param array $config * @param bool $isMaster * @return mixed - * @throws RedisConnectException * @throws Exception */ public function getConnection(array $config, $isMaster = false): mixed @@ -41,8 +44,6 @@ class Redis extends Pool $coroutineName = $this->name('redis:' . $name, $isMaster); if (Context::hasContext($coroutineName)) { return Context::getContext($coroutineName); - } else if (!$this->hasItem($coroutineName)) { - return $this->saveClient($coroutineName, $this->createConnect($config, $coroutineName)); } return $this->getByChannel($coroutineName, $config); } @@ -56,14 +57,14 @@ class Redis extends Pool */ public function getByChannel($coroutineName, $config): mixed { - if (!$this->hasItem($coroutineName)) { - return $this->saveClient($coroutineName, $this->createConnect($config, $coroutineName)); + if ($this->_create < $this->max && !$this->hasItem($coroutineName)) { + $this->createConnect($config, $coroutineName); } - $clients = $this->get($coroutineName); - if ($clients[1] === null) { + [$time, $clients] = $this->get($coroutineName); + if ($clients === null) { return $this->getByChannel($coroutineName, $config); } - return $this->saveClient($coroutineName, $clients[1]); + return $this->saveClient($coroutineName, $clients); } @@ -82,26 +83,41 @@ class Redis extends Pool /** * @param array $config * @param string $coroutineName - * @return SRedis - * @throws RedisConnectException + * @throws Exception */ - private function createConnect(array $config, string $coroutineName): SRedis + private function createConnect(array $config, string $coroutineName): void { - $redis = new SRedis(); - if (!$redis->connect($config['host'], (int)$config['port'], $config['timeout'])) { - throw new RedisConnectException(sprintf('The Redis Connect %s::%d Fail.', $config['host'], $config['port'])); + try { + if ($this->_create >= $this->max) { + return; + } + $this->_create += 1; + if (Context::hasContext('at_create_db')) { + return; + } + Context::setContext('at_create_db', 1); + $redis = new SRedis(); + if (!$redis->connect($config['host'], (int)$config['port'], $config['timeout'])) { + throw new RedisConnectException(sprintf('The Redis Connect %s::%d Fail.', $config['host'], $config['port'])); + } + if (empty($config['auth']) || !$redis->auth($config['auth'])) { + throw new RedisConnectException(sprintf('Redis Error: %s, Host %s, Auth %s', $redis->getLastError(), $config['host'], $config['auth'])); + } + $this->success('create redis client -> ' . $config['host'] . ':' . $this->size($coroutineName)); + if (!isset($config['read_timeout'])) { + $config['read_timeout'] = 10; + } + $redis->select($config['databases']); + $redis->setOption(SRedis::OPT_READ_TIMEOUT, $config['read_timeout']); + $redis->setOption(SRedis::OPT_PREFIX, $config['prefix']); + + $this->push($coroutineName, $redis); + } catch (\Throwable $exception) { + $this->addError($exception->getMessage()); + } finally { + Context::deleteId('at_create_db'); } - if (empty($config['auth']) || !$redis->auth($config['auth'])) { - throw new RedisConnectException(sprintf('Redis Error: %s, Host %s, Auth %s', $redis->getLastError(), $config['host'], $config['auth'])); - } - $this->success('create redis client -> ' . $config['host'] . ':' . $this->size($coroutineName)); - if (!isset($config['read_timeout'])) { - $config['read_timeout'] = 10; - } - $redis->select($config['databases']); - $redis->setOption(SRedis::OPT_READ_TIMEOUT, $config['read_timeout']); - $redis->setOption(SRedis::OPT_PREFIX, $config['prefix']); - return $redis; + } /** @@ -130,6 +146,9 @@ class Redis extends Pool if (!Context::hasContext($coroutineName)) { return; } + + $this->_create -= 1; + $this->remove($coroutineName); $this->clean($coroutineName); } @@ -171,9 +190,12 @@ class Redis extends Pool } } + /** + * @param string $name + */ public function desc(string $name) { - // TODO: Implement desc() method. + $this->_create -= 1; }