From f398e066ffb5ce8840492c04277d3eb54f8364cd Mon Sep 17 00:00:00 2001 From: swoft-bot Date: Sat, 6 Oct 2018 14:17:38 +0800 Subject: [PATCH] Squashed 'src/framework/' changes from ba1657b..b3a45be MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit b3a45be fix error on trigger event handler (https://github.com/swoft-cloud/swoft-component/pull/196) b1a48cd fix a bug when warnings appear in the high version of swoole (https://github.com/swoft-cloud/swoft-component/pull/195) 9c4da9f 自定义组件支持别名配置 (https://github.com/swoft-cloud/swoft-component/pull/181) bccf7a6 修复restart不能正常使用的BUG (https://github.com/swoft-cloud/swoft-component/pull/180) 97bfe2e 修改连接池配置的timeout字段为float (https://github.com/swoft-cloud/swoft-component/pull/177) 525097b 修改自定义组件只能扫描Aop、Command、Bootstrap三个文件的BUG (https://github.com/swoft-cloud/swoft-component/pull/169) 0b5f320 兼容swoole 4.0.3版本 (https://github.com/swoft-cloud/swoft-component/pull/166) 1d11b56 增加用户自定义组件配置 (https://github.com/swoft-cloud/swoft-component/pull/150) git-subtree-dir: src/framework git-subtree-split: b3a45be705c9cb53cb357925e228e4f60e6d76d5 --- .travis.yml | 2 +- composer.json | 3 +- src/Bean/Resource/AnnotationResource.php | 14 ++++ .../Resource/CustomComponentsRegister.php | 80 +++++++++++++++++++ .../Resource/ServerAnnotationResource.php | 4 + .../Resource/WorkerAnnotationResource.php | 4 + src/Bootstrap/Server/AbstractServer.php | 14 ++-- src/Core/Coroutine.php | 4 +- src/Event/LazyListener.php | 2 +- src/Pool/ConnectionPool.php | 13 ++- src/Pool/PoolConfigInterface.php | 4 +- src/Pool/PoolProperties.php | 6 +- src/Testing/SwooleResponse.php | 5 +- test/Cases/BeanTest.php | 23 ++++++ test/Cases/Connection/DemoConnection.php | 33 ++++++++ test/Cases/CorouotineTest.php | 22 +++++ test/Cases/Pool/DemoPool.php | 33 ++++++++ test/Cases/Pool/DemoPoolConfig.php | 16 ++++ test/Cases/PoolTest.php | 39 +++++++++ test/Testing/Bean/Config.php | 27 +++++++ test/Testing/Bean2/Config.php | 27 +++++++ test/config/properties/app.php | 7 ++ 22 files changed, 361 insertions(+), 21 deletions(-) create mode 100644 src/Bean/Resource/CustomComponentsRegister.php create mode 100644 test/Cases/Connection/DemoConnection.php create mode 100644 test/Cases/CorouotineTest.php create mode 100644 test/Cases/Pool/DemoPool.php create mode 100644 test/Cases/Pool/DemoPoolConfig.php create mode 100644 test/Testing/Bean/Config.php create mode 100644 test/Testing/Bean2/Config.php diff --git a/.travis.yml b/.travis.yml index 349a17593..bbcc3b298 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,7 @@ before_install: install: - wget https://github.com/redis/hiredis/archive/v0.13.3.tar.gz -O hiredis.tar.gz && mkdir -p hiredis && tar -xf hiredis.tar.gz -C hiredis --strip-components=1 && cd hiredis && sudo make -j$(nproc) && sudo make install && sudo ldconfig && cd .. - echo 'no' | pecl install -f redis - - wget https://github.com/swoole/swoole-src/archive/v4.0.2.tar.gz -O swoole.tar.gz && mkdir -p swoole && tar -xf swoole.tar.gz -C swoole --strip-components=1 && rm swoole.tar.gz && cd swoole && phpize && ./configure --enable-async-redis && make -j$(nproc) && make install && cd - + - wget https://github.com/swoole/swoole-src/archive/v4.0.3.tar.gz -O swoole.tar.gz && mkdir -p swoole && tar -xf swoole.tar.gz -C swoole --strip-components=1 && rm swoole.tar.gz && cd swoole && phpize && ./configure --enable-async-redis && make -j$(nproc) && make install && cd - - echo "extension = swoole.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini before_script: diff --git a/composer.json b/composer.json index c659e5064..6708017d8 100644 --- a/composer.json +++ b/composer.json @@ -37,7 +37,8 @@ }, "autoload-dev": { "psr-4": { - "SwoftTest\\": "test/Cases" + "SwoftTest\\": "test/Cases", + "SwoftTest\\Testing\\": "test/Testing/" } }, "repositories": { diff --git a/src/Bean/Resource/AnnotationResource.php b/src/Bean/Resource/AnnotationResource.php index 2d6d72d66..a5196ee37 100644 --- a/src/Bean/Resource/AnnotationResource.php +++ b/src/Bean/Resource/AnnotationResource.php @@ -80,6 +80,12 @@ abstract class AnnotationResource extends AbstractResource 'Example', ]; + /** + * the custom components + * @var array + */ + protected $customComponents = []; + /** * AnnotationResource constructor. * @@ -88,6 +94,9 @@ abstract class AnnotationResource extends AbstractResource public function __construct(array $properties) { $this->properties = $properties; + if (isset($properties['components']['custom']) && is_array($properties['components']['custom'])) { + $this->customComponents = $properties['components']['custom']; + } } /** @@ -349,4 +358,9 @@ private function parseClassAnnotations(string $className, array $annotation, arr } } } + + public function getComponentNamespaces(): array + { + return $this->componentNamespaces; + } } diff --git a/src/Bean/Resource/CustomComponentsRegister.php b/src/Bean/Resource/CustomComponentsRegister.php new file mode 100644 index 000000000..d661e23cf --- /dev/null +++ b/src/Bean/Resource/CustomComponentsRegister.php @@ -0,0 +1,80 @@ +customComponents as $ns => $componentDir) { + if (is_int($ns)) { + $ns = $componentDir; + $componentDir = ComposerHelper::getDirByNamespace($ns); + $ns = rtrim($ns, "\\"); + $componentDir = rtrim($componentDir, "/"); + } + + $this->componentNamespaces[] = $ns; + $componentDir = alias($componentDir); + + foreach ($this->serverScan as $dir) { + $scanDir = $componentDir . DS . $dir; + if (!is_dir($scanDir)) { + continue; + } + + $scanNs = $ns . "\\" . $dir; + $this->scanNamespaces[$scanNs] = $scanDir; + } + } + } + + /** + * Register the worker namespace + * @author limx + */ + public function registerWorkerNamespace() + { + foreach ($this->customComponents as $ns => $componentDir) { + if (is_int($ns)) { + $ns = $componentDir; + $componentDir = ComposerHelper::getDirByNamespace($ns); + $ns = rtrim($ns, "\\"); + $componentDir = rtrim($componentDir, "/"); + } + + $this->componentNamespaces[] = $ns; + $componentDir = alias($componentDir); + + if (!is_dir($componentDir)) { + continue; + } + + $scanDirs = scandir($componentDir, null); + + foreach ($scanDirs as $dir) { + if ($dir == '.' || $dir == '..') { + continue; + } + if (\in_array($dir, $this->serverScan, true)) { + continue; + } + + $scanDir = $componentDir . DS . $dir; + + if (!is_dir($scanDir)) { + $this->scanFiles[$ns][] = $scanDir; + continue; + } + $scanNs = $ns . '\\' . $dir; + + $this->scanNamespaces[$scanNs] = $scanDir; + } + } + } +} \ No newline at end of file diff --git a/src/Bean/Resource/ServerAnnotationResource.php b/src/Bean/Resource/ServerAnnotationResource.php index 2dd659e43..1f0377135 100644 --- a/src/Bean/Resource/ServerAnnotationResource.php +++ b/src/Bean/Resource/ServerAnnotationResource.php @@ -9,6 +9,8 @@ */ class ServerAnnotationResource extends AnnotationResource { + use CustomComponentsRegister; + /** * Register the scaned namespace */ @@ -46,5 +48,7 @@ public function registerNamespace() $this->scanNamespaces[$scanNs] = $scanDir; } } + + $this->registerServerNamespace(); } } \ No newline at end of file diff --git a/src/Bean/Resource/WorkerAnnotationResource.php b/src/Bean/Resource/WorkerAnnotationResource.php index 7543b0b44..f9b85ebb9 100644 --- a/src/Bean/Resource/WorkerAnnotationResource.php +++ b/src/Bean/Resource/WorkerAnnotationResource.php @@ -16,6 +16,8 @@ */ class WorkerAnnotationResource extends AnnotationResource { + use CustomComponentsRegister; + /** * Register the scaned namespace */ @@ -67,5 +69,7 @@ public function registerNamespace() $this->scanNamespaces[$scanNs] = $scanDir; } } + + $this->registerWorkerNamespace(); } } diff --git a/src/Bootstrap/Server/AbstractServer.php b/src/Bootstrap/Server/AbstractServer.php index 2ea9cdb1c..ccdd62cb0 100644 --- a/src/Bootstrap/Server/AbstractServer.php +++ b/src/Bootstrap/Server/AbstractServer.php @@ -127,23 +127,23 @@ public function reload($onlyTask = false) */ public function stop(): bool { - //获取master进程ID + // 获取master进程ID $masterPid = $this->serverSetting['masterPid']; - //使用swoole_process::kill代替posix_kill + // 使用swoole_process::kill代替posix_kill $result = \swoole_process::kill($masterPid); $timeout = 60; $startTime = time(); while (true) { - //检测进程是否退出 - if(!\swoole_process::kill($masterPid, 0)) { - //判断是否超时 - if(time() - $startTime >= $timeout) { + // Check the process status + if (\swoole_process::kill($masterPid, 0)) { + // 判断是否超时 + if (time() - $startTime >= $timeout) { return false; } usleep(10000); continue; } - + return true; } } diff --git a/src/Core/Coroutine.php b/src/Core/Coroutine.php index 0c0e6bb7d..e388f8972 100644 --- a/src/Core/Coroutine.php +++ b/src/Core/Coroutine.php @@ -102,7 +102,7 @@ public static function resume($coroutineId) */ public static function isSupportCoroutine(): bool { - if (swoole_version() >= '2.0.11') { + if (version_compare(swoole_version(), '2.0.11', '>=')) { return true; } else { return App::isWorkerStatus(); @@ -119,6 +119,6 @@ public static function isSupportCoroutine(): bool */ public static function shouldWrapCoroutine() { - return App::isWorkerStatus() && swoole_version() >= '2.0.11'; + return App::isWorkerStatus() && version_compare(swoole_version(), '2.0.11', '>='); } } diff --git a/src/Event/LazyListener.php b/src/Event/LazyListener.php index 74ca54a4d..ea97d9a82 100644 --- a/src/Event/LazyListener.php +++ b/src/Event/LazyListener.php @@ -27,7 +27,7 @@ public function __construct(callable $callback) */ public function handle(EventInterface $event) { - return PhpHelper::call($this->callback, $event); + return PhpHelper::call($this->callback, [$event]); } /** diff --git a/src/Pool/ConnectionPool.php b/src/Pool/ConnectionPool.php index 061e4dd21..5ef90717d 100644 --- a/src/Pool/ConnectionPool.php +++ b/src/Pool/ConnectionPool.php @@ -245,9 +245,18 @@ private function getConnectionByChannel(): ConnectionInterface return $this->channel->pop(); } + // When swoole version is larger than 4.0.3, Channel->select is removed. + if (version_compare(swoole_version(), '4.0.3', '>=')) { + $result = $this->channel->pop($maxWaitTime); + if ($result === false) { + throw new ConnectionException('Connection pool waiting queue timeout, timeout=' . $maxWaitTime); + } + return $result; + } + $writes = []; - $reads = [$this->channel]; - $result = $this->channel->select($reads, $writes, $maxWaitTime); + $reads = [$this->channel]; + $result = $this->channel->select($reads, $writes, $maxWaitTime); if ($result === false || empty($reads)) { throw new ConnectionException('Connection pool waiting queue timeout, timeout='.$maxWaitTime); diff --git a/src/Pool/PoolConfigInterface.php b/src/Pool/PoolConfigInterface.php index 854b8310e..85d03801d 100644 --- a/src/Pool/PoolConfigInterface.php +++ b/src/Pool/PoolConfigInterface.php @@ -27,9 +27,9 @@ public function getMaxActive(): int; public function getMaxWait(): int; /** - * @return int + * @return float */ - public function getTimeout(): int; + public function getTimeout(): float; /** * @return array diff --git a/src/Pool/PoolProperties.php b/src/Pool/PoolProperties.php index 133937438..957f0bade 100644 --- a/src/Pool/PoolProperties.php +++ b/src/Pool/PoolProperties.php @@ -53,7 +53,7 @@ class PoolProperties implements PoolConfigInterface /** * Connection timeout * - * @var int + * @var float */ protected $timeout = 3; @@ -126,9 +126,9 @@ public function getMaxWait(): int } /** - * @return int + * @return float */ - public function getTimeout(): int + public function getTimeout(): float { return $this->timeout; } diff --git a/src/Testing/SwooleResponse.php b/src/Testing/SwooleResponse.php index 63daedfc1..131ac532b 100644 --- a/src/Testing/SwooleResponse.php +++ b/src/Testing/SwooleResponse.php @@ -52,9 +52,10 @@ public function cookie($name, $value = null, $expires = null, $path = null, $dom /** * 设置HttpCode,如404, 501, 200 - * @param $code + * @param int $code + * @param string $reason */ - public function status($code) + public function status($code, $reason = NULL) { } diff --git a/test/Cases/BeanTest.php b/test/Cases/BeanTest.php index 9f0f25b22..fb444c720 100644 --- a/test/Cases/BeanTest.php +++ b/test/Cases/BeanTest.php @@ -9,9 +9,12 @@ */ namespace SwoftTest; +use Swoft\App; +use Swoft\Bean\Resource\ServerAnnotationResource; use Swoft\Proxy\Proxy; use SwoftTest\Bean\ProxyTest; use SwoftTest\Bean\TestHandler; +use SwoftTest\Testing\Bean\Config; /** * Class BeanTest @@ -39,4 +42,24 @@ public function testProxy() $this->assertEquals('p1p2beforeafter', $proxy->publicFun2Trait('p1', 'p2')); $this->assertEquals('p1p2beforeafter', $proxy->publicFun3Trait('p1', 'p2')); } + + public function testCustomComponentNamespaces() + { + $config = App::getProperties()->toArray(); + $this->assertArrayHasKey('components', $config); + $resource = new ServerAnnotationResource($config); + $resource->registerNamespace(); + + $namespace = $resource->getComponentNamespaces(); + $this->assertNotFalse(array_search('SwoftTest', $namespace)); + } + + public function testCustomComponentSupportAlias() + { + $config = bean(Config::class); + $this->assertEquals('test', $config->getName()); + + $config = bean(\SwoftTest\Testing\Bean2\Config::class); + $this->assertEquals('test', $config->getName()); + } } diff --git a/test/Cases/Connection/DemoConnection.php b/test/Cases/Connection/DemoConnection.php new file mode 100644 index 000000000..fe8a686db --- /dev/null +++ b/test/Cases/Connection/DemoConnection.php @@ -0,0 +1,33 @@ +connection = new \stdClass(); + $this->connection->id = uniqid(); + } + + public function reconnect() + { + $this->createConnection(); + } + + public function check(): bool + { + return true; + } + + public function getConnection() + { + return $this->connection; + } +} \ No newline at end of file diff --git a/test/Cases/CorouotineTest.php b/test/Cases/CorouotineTest.php new file mode 100644 index 000000000..383aebe4f --- /dev/null +++ b/test/Cases/CorouotineTest.php @@ -0,0 +1,22 @@ +assertTrue(Coroutine::isSupportCoroutine()); + } + + public function testShouldWrapCoroutine() + { + $this->assertFalse(Coroutine::shouldWrapCoroutine()); + } +} \ No newline at end of file diff --git a/test/Cases/Pool/DemoPool.php b/test/Cases/Pool/DemoPool.php new file mode 100644 index 000000000..d00fa38eb --- /dev/null +++ b/test/Cases/Pool/DemoPool.php @@ -0,0 +1,33 @@ +assertEquals(2, $pConfig->getInterval()); $this->assertEquals([1, 2], $pConfig->getTags()); } + + public function testGetConnection() + { + $pool = bean(DemoPool::class); + $connection = $pool->getConnection(); + $connection2 = $pool->getConnection(); + + $id = $connection->getConnection()->id; + $id2 = $connection2->getConnection()->id; + + $this->assertNotEquals($id, $id2); + + $connection->release(true); + $connection->receive(); + $connection3 = $pool->getConnection(); + $id3 = $connection3->getConnection()->id; + $this->assertEquals($id, $id3); + + $connection2->release(true); + $connection3->release(true); + } + + public function testGetConnectionByCo() + { + go(function () { + $this->testGetConnection(); + }); + } + + public function testPoolConfigTimeout() + { + $pConfig = App::getBean(EnvPoolConfig::class); + $this->assertEquals($pConfig->getTimeout(), 2); + + $dConfig = App::getBean(DemoPoolConfig::class); + $this->assertEquals($dConfig->getTimeout(), 0.5); + } } diff --git a/test/Testing/Bean/Config.php b/test/Testing/Bean/Config.php new file mode 100644 index 000000000..d0e799116 --- /dev/null +++ b/test/Testing/Bean/Config.php @@ -0,0 +1,27 @@ +name; + } +} \ No newline at end of file diff --git a/test/Testing/Bean2/Config.php b/test/Testing/Bean2/Config.php new file mode 100644 index 000000000..b79fce781 --- /dev/null +++ b/test/Testing/Bean2/Config.php @@ -0,0 +1,27 @@ +name; + } +} \ No newline at end of file diff --git a/test/config/properties/app.php b/test/config/properties/app.php index 553e6d11a..05b654317 100644 --- a/test/config/properties/app.php +++ b/test/config/properties/app.php @@ -17,6 +17,13 @@ ], 'bootScan' => [], 'env' => 'Base', + 'components' => [ + 'custom' => [ + 'SwoftTest', + 'SwoftTest\\Testing\\Bean' => BASE_PATH . '/Testing/Bean', + 'SwoftTest\\Testing\\Bean2' => '@root/Testing/Bean2', + ] + ], 'provider' => require __DIR__ . DS . 'provider.php', 'test' => require __DIR__ . DS . 'test.php', ];