From 0f6813f0fdcdd5f46f46a95b07bd942e03340f5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=93=AD=E6=98=95?= <715557344@qq.com> Date: Fri, 5 Jan 2024 21:58:12 +0800 Subject: [PATCH] first commit --- .gitattributes | 2 + .github/workflows/release.yml | 25 ++++++ .github/workflows/test.yml | 68 +++++++++++++++++ .gitignore | 5 ++ .php-cs-fixer.php | 96 ++++++++++++++++++++++++ .phpstorm.meta.php | 6 ++ LICENSE | 21 ++++++ README.md | 12 +++ composer.json | 54 +++++++++++++ phpunit.xml | 15 ++++ src/ConfigProvider.php | 29 +++++++ src/Listener/BootRPCConsumerListener.php | 91 ++++++++++++++++++++++ src/RPC/User/UserInterface.php | 20 +++++ tests/Cases/AbstractTestCase.php | 22 ++++++ tests/Cases/ExampleTest.php | 34 +++++++++ tests/bootstrap.php | 12 +++ 16 files changed, 512 insertions(+) create mode 100644 .gitattributes create mode 100644 .github/workflows/release.yml create mode 100644 .github/workflows/test.yml create mode 100644 .gitignore create mode 100644 .php-cs-fixer.php create mode 100644 .phpstorm.meta.php create mode 100644 LICENSE create mode 100644 README.md create mode 100644 composer.json create mode 100644 phpunit.xml create mode 100644 src/ConfigProvider.php create mode 100644 src/Listener/BootRPCConsumerListener.php create mode 100644 src/RPC/User/UserInterface.php create mode 100644 tests/Cases/AbstractTestCase.php create mode 100644 tests/Cases/ExampleTest.php create mode 100644 tests/bootstrap.php diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..27b765f --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +/tests export-ignore +/.github export-ignore diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..0f7d23f --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,25 @@ +on: + push: + # Sequence of patterns matched against refs/tags + tags: + - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 + +name: Release + +jobs: + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: Release ${{ github.ref }} + draft: false + prerelease: false diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..f31ad78 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,68 @@ +name: PHPUnit + +on: [ push, pull_request ] + +env: + SWOOLE_VERSION: '5.1.1' + SWOW_VERSION: 'v1.2.0' + +jobs: + ci: + name: Test PHP ${{ matrix.php-version }} on ${{ matrix.engine }} + runs-on: "${{ matrix.os }}" + strategy: + matrix: + os: [ ubuntu-latest ] + php-version: [ '8.1', '8.2', '8.3' ] + engine: [ 'none', 'swoole', 'swow' ] + max-parallel: 9 + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + tools: phpize + ini-values: opcache.enable_cli=0 + coverage: none + - name: Setup Swoole + if: ${{ matrix.engine == 'swoole' }} + run: | + cd /tmp + sudo apt-get update + sudo apt-get install libcurl4-openssl-dev libc-ares-dev libpq-dev + wget https://github.com/swoole/swoole-src/archive/v${SWOOLE_VERSION}.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-openssl --enable-swoole-curl --enable-cares --enable-swoole-pgsql + make -j$(nproc) + sudo make install + sudo sh -c "echo extension=swoole > /etc/php/${{ matrix.php-version }}/cli/conf.d/swoole.ini" + php --ri swoole + - name: Setup Swow + if: ${{ matrix.engine == 'swow' }} + run: | + cd /tmp + wget https://github.com/swow/swow/archive/"${SWOW_VERSION}".tar.gz -O swow.tar.gz + mkdir -p swow + tar -xf swow.tar.gz -C swow --strip-components=1 + rm swow.tar.gz + cd swow/ext || exit + + phpize + ./configure --enable-swow --enable-swow-ssl --enable-swow-curl + make -j "$(nproc)" + sudo make install + sudo sh -c "echo extension=swow > /etc/php/${{ matrix.php-version }}/cli/conf.d/swow.ini" + php --ri swow + - name: Setup Packages + run: composer update -o --no-scripts + - name: Run Test Cases + run: | + vendor/bin/php-cs-fixer fix --dry-run + composer analyse + composer test diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..628a5fc --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +/.idea +/vendor/ +composer.lock +*.cache +*.log \ No newline at end of file diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php new file mode 100644 index 0000000..6480048 --- /dev/null +++ b/.php-cs-fixer.php @@ -0,0 +1,96 @@ +setRiskyAllowed(true) + ->setRules([ + '@PSR2' => true, + '@Symfony' => true, + '@DoctrineAnnotation' => true, + '@PhpCsFixer' => true, + 'header_comment' => [ + 'comment_type' => 'PHPDoc', + 'header' => $header, + 'separate' => 'none', + 'location' => 'after_declare_strict', + ], + 'array_syntax' => [ + 'syntax' => 'short' + ], + 'list_syntax' => [ + 'syntax' => 'short' + ], + 'concat_space' => [ + 'spacing' => 'one' + ], + 'blank_line_before_statement' => [ + 'statements' => [ + 'declare', + ], + ], + 'general_phpdoc_annotation_remove' => [ + 'annotations' => [ + 'author' + ], + ], + 'ordered_imports' => [ + 'imports_order' => [ + 'class', 'function', 'const', + ], + 'sort_algorithm' => 'alpha', + ], + 'single_line_comment_style' => [ + 'comment_types' => [ + ], + ], + 'yoda_style' => [ + 'always_move_variable' => false, + 'equal' => false, + 'identical' => false, + ], + 'phpdoc_align' => [ + 'align' => 'left', + ], + 'multiline_whitespace_before_semicolons' => [ + 'strategy' => 'no_multi_line', + ], + 'constant_case' => [ + 'case' => 'lower', + ], + 'global_namespace_import' => [ + 'import_classes' => true, + 'import_constants' => true, + 'import_functions' => true, + ], + 'phpdoc_to_comment' => false, + 'class_attributes_separation' => true, + 'combine_consecutive_unsets' => true, + 'declare_strict_types' => true, + 'linebreak_after_opening_tag' => true, + 'lowercase_static_reference' => true, + 'no_useless_else' => true, + 'no_unused_imports' => true, + 'not_operator_with_successor_space' => true, + 'not_operator_with_space' => false, + 'ordered_class_elements' => true, + 'php_unit_strict' => false, + 'phpdoc_separation' => false, + 'single_quote' => true, + 'standardize_not_equals' => true, + 'multiline_comment_opening_closing' => true, + 'single_line_empty_body' => false, + ]) + ->setFinder( + PhpCsFixer\Finder::create() + ->exclude('vendor') + ->in(__DIR__) + ) + ->setUsingCache(false); diff --git a/.phpstorm.meta.php b/.phpstorm.meta.php new file mode 100644 index 0000000..1014069 --- /dev/null +++ b/.phpstorm.meta.php @@ -0,0 +1,6 @@ +=8.1", + "hyperf/config": "^3.1", + "hyperf/event": "^3.1", + "hyperf/framework": "^3.1", + "hyperf/rpc-multiplex": "^3.1", + "hyperf/support": "^3.1" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.0", + "mockery/mockery": "^1.0", + "phpstan/phpstan": "^1.0", + "phpunit/phpunit": "^10.0", + "swoole/ide-helper": "dev-master" + }, + "suggest": { + "swow/swow": "Required to create swow components." + }, + "minimum-stability": "dev", + "prefer-stable": true, + "config": { + "optimize-autoloader": true, + "sort-packages": true + }, + "scripts": { + "test": "phpunit -c phpunit.xml --colors=always", + "analyse": "phpstan analyse --memory-limit 1024M -l 0 ./src", + "cs-fix": "php-cs-fixer fix $1" + }, + "extra": { + "hyperf": { + "config": "GeminiD\\PltCommon\\ConfigProvider" + } + } +} diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..16b9c39 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,15 @@ + + + + ./tests/ + + diff --git a/src/ConfigProvider.php b/src/ConfigProvider.php new file mode 100644 index 0000000..7fd8fad --- /dev/null +++ b/src/ConfigProvider.php @@ -0,0 +1,29 @@ + [ + 'scan' => [ + 'paths' => [ + __DIR__, + ], + ], + ], + ]; + } +} diff --git a/src/Listener/BootRPCConsumerListener.php b/src/Listener/BootRPCConsumerListener.php new file mode 100644 index 0000000..67c49a7 --- /dev/null +++ b/src/Listener/BootRPCConsumerListener.php @@ -0,0 +1,91 @@ + ['plt-user', 9502], + ]; + + $consumers = []; + foreach ($interfaces as $interface => [$host, $port]) { + $consumers[] = $this->getConsumer($interface, $host, $port); + } + + $this->container->get(ConfigInterface::class)->set('services.consumers', $consumers); + } + + protected function getConsumer(string $interface, string $host, int $port): array + { + $key = strtoupper('RPC_' . StrCache::studly('plt-user', '_')); + $value = env($key); + if ($value) { + // RPC_PLT_USER="127.0.0.1:10001" + // host=127.0.0.1 port=10001 + [$host, $port] = explode(':', $value); + } + + return [ + 'name' => $interface::NAME, + 'service' => $interface, + 'id' => $interface, + 'protocol' => Constant::PROTOCOL_DEFAULT, + 'load_balancer' => 'random', + 'nodes' => [ + ['host' => $host, 'port' => (int) $port], + ], + 'options' => [ + 'connect_timeout' => 5.0, + 'recv_timeout' => 5.0, + 'settings' => [ + // 包体最大值,若小于 Server 返回的数据大小,则会抛出异常,故尽量控制包体大小 + 'package_max_length' => 1024 * 1024 * 2, + ], + // 重试次数,默认值为 2 + 'retry_count' => 2, + // 重试间隔,毫秒 + 'retry_interval' => 100, + // 多路复用客户端数量 + 'client_count' => 4, + // 心跳间隔 非 numeric 表示不开启心跳 + 'heartbeat' => 30, + ], + ]; + } +} diff --git a/src/RPC/User/UserInterface.php b/src/RPC/User/UserInterface.php new file mode 100644 index 0000000..04f02c8 --- /dev/null +++ b/src/RPC/User/UserInterface.php @@ -0,0 +1,20 @@ +assertTrue(true); + } + + public function testStudly() + { + $host = strtoupper('RPC_' . StrCache::studly('plt-user', '_')); + + $this->assertSame('RPC_PLT_USER', $host); + } +} diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 0000000..6ce15df --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,12 @@ +