From ed105cd6cf68692f6a18c37b7168df14115d12b6 Mon Sep 17 00:00:00 2001 From: Masiukevich Maksim Date: Sun, 3 Jan 2021 17:42:11 +0100 Subject: [PATCH] Update ridge (#21) * Migrate to PHP 8 Authored-by: Masiukevich Maksim --- CHANGELOG.md => .github/CHANGELOG.md | 0 CONDUCT.md => .github/CONDUCT.md | 0 CONTRIBUTING.md => .github/CONTRIBUTING.md | 0 .../ISSUE_TEMPLATE.md | 0 .../PULL_REQUEST_TEMPLATE.md | 0 .github/workflows/continuous-integration.yml | 114 ++ .scrutinizer.yml | 66 - .travis.yml | 29 - README.md | 14 +- benchmarks/AbstractBench.php | 80 -- benchmarks/ConsumeBench.php | 52 - benchmarks/ProduceBench.php | 32 - composer.json | 102 +- phpbench.json | 3 - phpstan.neon | 13 + phpunit.xml | 42 +- psalm.xml | 25 + src/Buffer.php | 193 ++- src/Channel.php | 1181 ++++++++--------- src/Client.php | 451 +++---- src/Config.php | 268 ++-- src/Connection.php | 174 ++- src/Constants.php | 256 ++-- src/Consumer.php | 45 +- src/Events.php | 51 +- src/Exception/ChannelException.php | 51 +- src/Exception/ClassInvalid.php | 5 +- src/Exception/ClientException.php | 54 +- src/Exception/ConfigurationException.php | 29 + src/Exception/ConnectionException.php | 33 + src/Exception/MethodInvalid.php | 6 +- src/Exception/ProtocolException.php | 59 +- src/Message.php | 134 +- src/MessageReceiver.php | 102 +- src/Parser.php | 342 ++--- src/Properties.php | 51 +- src/Protocol/AbstractFrame.php | 20 +- src/Protocol/AcknowledgmentFrame.php | 2 +- src/Protocol/BasicAckFrame.php | 17 +- src/Protocol/BasicCancelFrame.php | 17 +- src/Protocol/BasicCancelOkFrame.php | 17 +- src/Protocol/BasicConsumeFrame.php | 23 +- src/Protocol/BasicConsumeOkFrame.php | 15 +- src/Protocol/BasicDeliverFrame.php | 25 +- src/Protocol/BasicGetEmptyFrame.php | 17 +- src/Protocol/BasicGetFrame.php | 21 +- src/Protocol/BasicGetOkFrame.php | 25 +- src/Protocol/BasicNackFrame.php | 17 +- src/Protocol/BasicPublishFrame.php | 23 +- src/Protocol/BasicQosFrame.php | 21 +- src/Protocol/BasicRecoverAsyncFrame.php | 17 +- src/Protocol/BasicRecoverFrame.php | 17 +- src/Protocol/BasicRejectFrame.php | 13 +- src/Protocol/BasicReturnFrame.php | 23 +- src/Protocol/ChannelCloseFrame.php | 25 +- src/Protocol/ChannelFlowFrame.php | 13 +- src/Protocol/ChannelFlowOkFrame.php | 15 +- src/Protocol/ChannelOpenFrame.php | 19 +- src/Protocol/ChannelOpenOkFrame.php | 17 +- src/Protocol/ConfirmSelectFrame.php | 17 +- src/Protocol/ConnectionBlockedFrame.php | 17 +- src/Protocol/ConnectionCloseFrame.php | 23 +- src/Protocol/ConnectionOpenFrame.php | 25 +- src/Protocol/ConnectionOpenOkFrame.php | 19 +- src/Protocol/ConnectionSecureFrame.php | 17 +- src/Protocol/ConnectionSecureOkFrame.php | 15 +- src/Protocol/ConnectionStartFrame.php | 44 +- src/Protocol/ConnectionStartOkFrame.php | 23 +- src/Protocol/ConnectionTuneFrame.php | 23 +- src/Protocol/ConnectionTuneOkFrame.php | 23 +- src/Protocol/ContentBodyFrame.php | 2 +- src/Protocol/ContentHeaderFrame.php | 169 ++- src/Protocol/ExchangeBindFrame.php | 25 +- src/Protocol/ExchangeDeclareFrame.php | 19 +- src/Protocol/ExchangeDeleteFrame.php | 21 +- src/Protocol/ExchangeUnbindFrame.php | 25 +- src/Protocol/MethodFrame.php | 20 +- src/Protocol/QueueBindFrame.php | 28 +- src/Protocol/QueueDeclareFrame.php | 21 +- src/Protocol/QueueDeclareOkFrame.php | 19 +- src/Protocol/QueueDeleteFrame.php | 19 +- src/Protocol/QueueDeleteOkFrame.php | 15 +- src/Protocol/QueuePurgeFrame.php | 19 +- src/Protocol/QueuePurgeOkFrame.php | 15 +- src/Protocol/QueueUnbindFrame.php | 19 +- src/Queue.php | 18 +- tests/ConfigTest.php | 32 +- tests/RidgeTest.php | 4 +- 88 files changed, 2184 insertions(+), 3028 deletions(-) rename CHANGELOG.md => .github/CHANGELOG.md (100%) rename CONDUCT.md => .github/CONDUCT.md (100%) rename CONTRIBUTING.md => .github/CONTRIBUTING.md (100%) rename ISSUE_TEMPLATE.md => .github/ISSUE_TEMPLATE.md (100%) rename PULL_REQUEST_TEMPLATE.md => .github/PULL_REQUEST_TEMPLATE.md (100%) create mode 100644 .github/workflows/continuous-integration.yml delete mode 100644 .scrutinizer.yml delete mode 100644 .travis.yml delete mode 100644 benchmarks/AbstractBench.php delete mode 100644 benchmarks/ConsumeBench.php delete mode 100644 benchmarks/ProduceBench.php delete mode 100644 phpbench.json create mode 100644 phpstan.neon create mode 100644 psalm.xml create mode 100644 src/Exception/ConfigurationException.php create mode 100644 src/Exception/ConnectionException.php diff --git a/CHANGELOG.md b/.github/CHANGELOG.md similarity index 100% rename from CHANGELOG.md rename to .github/CHANGELOG.md diff --git a/CONDUCT.md b/.github/CONDUCT.md similarity index 100% rename from CONDUCT.md rename to .github/CONDUCT.md diff --git a/CONTRIBUTING.md b/.github/CONTRIBUTING.md similarity index 100% rename from CONTRIBUTING.md rename to .github/CONTRIBUTING.md diff --git a/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md similarity index 100% rename from ISSUE_TEMPLATE.md rename to .github/ISSUE_TEMPLATE.md diff --git a/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md similarity index 100% rename from PULL_REQUEST_TEMPLATE.md rename to .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml new file mode 100644 index 0000000..c18733d --- /dev/null +++ b/.github/workflows/continuous-integration.yml @@ -0,0 +1,114 @@ +name: "Continuous Integration" + +on: [ push, pull_request ] + +jobs: + psalm: + name: Psalm + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 8.0 + coverage: none + tools: composer:v2 + + - name: Install dependencies with composer + run: composer install -ov + + - name: Run vimeo/psalm + run: ./vendor/bin/psalm --config=psalm.xml --shepherd + + phpstan: + name: PHPStan + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 8.0 + coverage: none + tools: composer:v2 + + - name: Install dependencies with composer + run: composer install -ov + + - name: Run phpstan/phpstan + run: ./vendor/bin/phpstan analyse src --level 7 + + phpunit: + name: PHPUnit + + runs-on: ubuntu-latest + services: + rabbitmq: + image: rabbitmq:alpine + ports: + - 5672:5672 + env: + RABBITMQ_DEFAULT_USER: guest + RABBITMQ_DEFAULT_PASS: guest + options: --health-cmd "rabbitmqctl node_health_check" --health-interval 10s --health-timeout 5s --health-retries 5 + + env: + PHP_EXTENSIONS: mbstring, dom, intl, json, libxml, xml, xmlwriter, sockets + PHP_INI_VALUES: assert.exception=1, zend.assertions=1 + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Install PHP with extensions + uses: shivammathur/setup-php@v2 + with: + php-version: 8.0 + extensions: ${{ env.PHP_EXTENSIONS }} + ini-values: ${{ env.PHP_INI_VALUES }} + tools: composer:v2 + + - name: Install dependencies + run: composer update -ov + + - name: Await + uses: jakejarvis/wait-action@master + + - name: Run tests with phpunit + run: XDEBUG_MODE=coverage php ./vendor/bin/phpunit --configuration ./phpunit.xml --coverage-clover=coverage.clover + + - name: Upload coverage file + uses: actions/upload-artifact@v2 + with: + name: phpunit.coverage + path: coverage.clover + + upload_coverage: + name: Upload coverage + runs-on: ubuntu-latest + needs: phpunit + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 7.4 + coverage: none + tools: composer + + - name: Download coverage files + uses: actions/download-artifact@v2 + with: + path: reports + + - name: Send code coverage report to Scrutinizer + run: | + wget https://scrutinizer-ci.com/ocular.phar + php ocular.phar code-coverage:upload --format=php-clover ./reports/phpunit.coverage/coverage.clover \ No newline at end of file diff --git a/.scrutinizer.yml b/.scrutinizer.yml deleted file mode 100644 index adaad00..0000000 --- a/.scrutinizer.yml +++ /dev/null @@ -1,66 +0,0 @@ -filter: - paths: [src/*] - excluded_paths: [tests/*] -tools: - php_analyzer: true - php_sim: true - php_pdepend: true - sensiolabs_security_checker: true - php_changetracking: true - php_mess_detector: - enabled: true - config: - ruleset: ~ - code_size_rules: - cyclomatic_complexity: true - npath_complexity: true - excessive_method_length: true - excessive_class_length: true - excessive_parameter_list: true - excessive_public_count: true - too_many_fields: true - too_many_methods: true - excessive_class_complexity: true - design_rules: - exit_expression: true - eval_expression: true - goto_statement: true - number_of_class_children: true - depth_of_inheritance: true - coupling_between_objects: true - unused_code_rules: - unused_private_field: true - unused_local_variable: true - unused_private_method: true - unused_formal_parameter: true - naming_rules: - short_variable: - minimum: 3 - long_variable: - maximum: 20 - short_method: - minimum: 3 - constructor_conflict: true - constant_naming: true - boolean_method_name: true - controversial_rules: - superglobals: true - camel_case_class_name: true - camel_case_property_name: true - camel_case_method_name: true - camel_case_parameter_name: true - camel_case_variable_name: true - external_code_coverage: - timeout: 600 -checks: - php: - code_rating: true - -build: - nodes: - analysis: - project_setup: - override: true - tests: - override: - - php-scrutinizer-run --enable-security-analysis diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 1f11046..0000000 --- a/.travis.yml +++ /dev/null @@ -1,29 +0,0 @@ -language: php - -php: - - 7.2 - - 7.3 - -addons: - apt: - packages: - - rabbitmq-server - -cache: - directories: - - $HOME/.cache/composer - -before_script: - - mkdir -p build/logs - -install: - - travis_retry composer install --no-interaction --no-suggest - - travis_retry wget -c -nc --retry-connrefused --tries=0 https://scrutinizer-ci.com/ocular.phar - - chmod +x ocular.phar - -script: - - ./vendor/bin/phpunit --configuration ./phpunit.xml --coverage-clover=coverage.clover - -after_script: - - if [ "$TRAVIS_PHP_VERSION" == "7.2" ]; then wget -c -nc --retry-connrefused --tries=0 https://scrutinizer-ci.com/ocular.phar; fi - - if [ "$TRAVIS_PHP_VERSION" == "7.2" ]; then php ocular.phar code-coverage:upload --format=php-clover coverage.clover; fi diff --git a/README.md b/README.md index bb3b354..18142d1 100644 --- a/README.md +++ b/README.md @@ -58,24 +58,16 @@ More examples can be found in [`examples`](examples) directory. ## Testing ```bash -$ composer test -``` - -## Benchmarks - -We run benchmarks as follow: - -```bash -$ RIDGE_BENCHMARK_DSN=amqp://user:pass@localhost:5672 composer bench +$ composer tests ``` ## Change log -Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently. +Please see [CHANGELOG](.github/CHANGELOG.md) for more information on what has changed recently. ## Contributing -Please see [CONTRIBUTING](CONTRIBUTING.md) and [CONDUCT](CONDUCT.md) for details. +Please see [CONTRIBUTING](.github/CONTRIBUTING.md) and [CONDUCT](.github/CONDUCT.md) for details. ## Security diff --git a/benchmarks/AbstractBench.php b/benchmarks/AbstractBench.php deleted file mode 100644 index 6a39c0d..0000000 --- a/benchmarks/AbstractBench.php +++ /dev/null @@ -1,80 +0,0 @@ -client = Client::create($dsn); - - yield $this->client->connect(); - - $this->channel = yield $this->client->channel(); - - yield $this->channel->queueDeclare('bench_queue'); - yield $this->channel->exchangeDeclare('bench_exchange'); - yield $this->channel->queueBind('bench_queue', 'bench_exchange'); - })); - } - - /** - * @return void - * @throws \Throwable - */ - public function clear(): void - { - wait(call(function () { - yield $this->channel->queueDelete('bench_queue'); - yield $this->channel->exchangeDelete('bench_exchange'); - - yield $this->client->disconnect(); - })); - } -} diff --git a/benchmarks/ConsumeBench.php b/benchmarks/ConsumeBench.php deleted file mode 100644 index 1f7ec0b..0000000 --- a/benchmarks/ConsumeBench.php +++ /dev/null @@ -1,52 +0,0 @@ -channel->publish($this->body, 'bench_exchange'); - } - - $promises[] = $this->channel->publish('quit', 'bench_exchange'); - - yield $promises; - })); - } - - /** - * @Revs(1) - * @Iterations(10) - * - * @return void - * @throws \Throwable - */ - public function benchConsume(): void - { - wait(call(function () { - yield $this->channel->consume(function (Message $message) { - if ($message->content() === 'quit') { - yield $this->client->disconnect(); - } - }, 'bench_queue', '', false, true); - })); - } - - public function clear(): void - { - } -} diff --git a/benchmarks/ProduceBench.php b/benchmarks/ProduceBench.php deleted file mode 100644 index 1417d92..0000000 --- a/benchmarks/ProduceBench.php +++ /dev/null @@ -1,32 +0,0 @@ -channel->publish($this->body, 'bench_exchange'); - } - - yield $promises; - })); - } -} diff --git a/composer.json b/composer.json index 4593eca..622e8fa 100644 --- a/composer.json +++ b/composer.json @@ -1,51 +1,57 @@ { - "name": "phpinnacle/ridge", - "type": "library", - "description": "PHPinnacle async AMQP client", - "keywords": [ - "phpinnacle", "async", "amqp" - ], - "homepage": "https://github.com/phpinnacle/ridge", - "license": "MIT", - "authors": [ - { - "name": "PHPinnacle", - "email": "dev@phpinnacle.com", - "homepage": "https://phpinnacle.com", - "role": "Developer" - } - ], - "require": { - "php": "^7.2", - "amphp/amp": "v2.5.*", - "amphp/socket": "v1.1.*", - "phpinnacle/buffer": "v1.0.*" - }, - "require-dev": { - "phpbench/phpbench": "^0.16", - "phpunit/phpunit": "^8.0" - }, - "autoload": { - "psr-4": { - "PHPinnacle\\Ridge\\": "src" - } - }, - "autoload-dev": { - "psr-4": { - "PHPinnacle\\Ridge\\Tests\\": "tests", - "PHPinnacle\\Ridge\\Bench\\": "benchmarks" - } - }, - "scripts": { - "test": "phpunit", - "bench": "phpbench run benchmarks --report=aggregate" - }, - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "config": { - "sort-packages": true + "name": "phpinnacle/ridge", + "type": "library", + "description": "PHPinnacle async AMQP client", + "keywords": [ + "phpinnacle", + "async", + "amqp" + ], + "homepage": "https://github.com/phpinnacle/ridge", + "license": "MIT", + "authors": [ + { + "name": "PHPinnacle", + "email": "dev@phpinnacle.com", + "homepage": "https://phpinnacle.com", + "role": "Developer" } + ], + "require": { + "php": ">=8.0", + "amphp/amp": "v2.5.*", + "amphp/socket": "v1.1.*", + "phpinnacle/buffer": "v1.2.*" + }, + "require-dev": { + "phpunit/phpunit": "v9.5.*", + "vimeo/psalm": "v4.3.*", + "phpstan/phpstan": "v0.12.*" + }, + "prefer-stable": true, + "autoload": { + "psr-4": { + "PHPinnacle\\Ridge\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "PHPinnacle\\Ridge\\Tests\\": "tests" + } + }, + "scripts": { + "psalm": "./vendor/bin/psalm --config=psalm.xml", + "phpstan": "./vendor/bin/phpstan analyse src --level 7", + "tests": "./vendor/bin/phpunit --configuration phpunit.xml --verbose", + "coverage": "./vendor/bin/phpunit --configuration phpunit.xml --coverage-html ./coverage --verbose" + }, + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "config": { + "sort-packages": true, + "optimize-autoloader": true + } } diff --git a/phpbench.json b/phpbench.json deleted file mode 100644 index 466f9e5..0000000 --- a/phpbench.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "bootstrap": "vendor/autoload.php" -} \ No newline at end of file diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..0d1e496 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,13 @@ +parameters: + checkGenericClassInNonGenericObjectType: false + checkMissingIterableValueType: false + ignoreErrors: + - + message: '#Unable to resolve the template type#' + path: %currentWorkingDirectory%/src + - + message: '#AbstractFrame given#' + path: %currentWorkingDirectory%/src/Channel.php + - + message: '#AbstractFrame given#' + path: %currentWorkingDirectory%/src/Client.php \ No newline at end of file diff --git a/phpunit.xml b/phpunit.xml index 1a43959..49cb4fc 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,35 +1,25 @@ - + + + + ./ + + + ./tests + ./vendor + + - + - tests + ./tests/ - - - src - - - - - - - - - diff --git a/psalm.xml b/psalm.xml new file mode 100644 index 0000000..d30e53e --- /dev/null +++ b/psalm.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + diff --git a/src/Buffer.php b/src/Buffer.php index cec8014..d5093b3 100644 --- a/src/Buffer.php +++ b/src/Buffer.php @@ -16,61 +16,48 @@ final class Buffer extends ByteBuffer { - /** - * @param string $value - * - * @return static - */ public function appendString(string $value): self { $this ->appendUint8(\strlen($value)) - ->append($value) - ; + ->append($value); return $this; } /** - * @return string + * @throws \PHPinnacle\Buffer\BufferOverflow */ public function consumeString(): string { return $this->consume($this->consumeUint8()); } - /** - * @param string $value - * - * @return self - */ public function appendText(string $value): self { $this ->appendUint32(\strlen($value)) - ->append($value) - ; + ->append($value); return $this; } /** - * @return string + * @throws \PHPinnacle\Buffer\BufferOverflow */ public function consumeText(): string { return $this->consume($this->consumeUint32()); } - /** - * @param array $bits - * - * @return self - */ public function appendBits(array $bits): self { $value = 0; + /** + * @var int $n + * @var bool $bit + */ foreach ($bits as $n => $bit) { $bit = $bit ? 1 : 0; $value |= $bit << $n; @@ -82,9 +69,7 @@ public function appendBits(array $bits): self } /** - * @param int $n - * - * @return bool[] + * @throws \PHPinnacle\Buffer\BufferOverflow */ public function consumeBits(int $n): array { @@ -98,11 +83,6 @@ public function consumeBits(int $n): array return $bits; } - /** - * @param \DateTimeInterface $value - * - * @return self - */ public function appendTimestamp(\DateTimeInterface $value): self { $this->appendUint64($value->getTimestamp()); @@ -110,28 +90,25 @@ public function appendTimestamp(\DateTimeInterface $value): self return $this; } - /** - * @noinspection PhpDocMissingThrowsInspection - * - * @return \DateTimeInterface - */ public function consumeTimestamp(): \DateTimeInterface { /** @noinspection PhpUnhandledExceptionInspection */ - return (new \DateTimeImmutable)->setTimestamp($this->consumeUint64()); + return new \DateTimeImmutable(\sprintf('@%s', $this->consumeUint64())); } /** - * @param array $table - * - * @return self + * @throws \PHPinnacle\Ridge\Exception\ProtocolException */ public function appendTable(array $table): self { - $buffer = new static; + $buffer = new self(); + /** + * @var string|ByteBuffer $k + * @var mixed $v + */ foreach ($table as $k => $v) { - $k = (string) $k; + $k = (string)$k; $buffer->appendUint8(\strlen($k)); $buffer->append($k); @@ -140,14 +117,13 @@ public function appendTable(array $table): self $this ->appendUint32($buffer->size()) - ->append($buffer) - ; + ->append($buffer); return $this; } /** - * @return array + * @throws \PHPinnacle\Buffer\BufferOverflow */ public function consumeTable(): array { @@ -162,28 +138,26 @@ public function consumeTable(): array } /** - * @param array $value - * - * @return self + * @throws \PHPinnacle\Ridge\Exception\ProtocolException */ public function appendArray(array $value): self { - $buffer = new static; + $buffer = new self(); + /** @var mixed $v */ foreach ($value as $v) { $buffer->appendValue($v); } $this ->appendUint32($buffer->size()) - ->append($buffer) - ; + ->append($buffer); return $this; } /** - * @return array + * @throws \PHPinnacle\Buffer\BufferOverflow */ public function consumeArray(): array { @@ -198,7 +172,7 @@ public function consumeArray(): array } /** - * @return int + * @throws \PHPinnacle\Buffer\BufferOverflow */ public function consumeDecimal(): int { @@ -209,73 +183,70 @@ public function consumeDecimal(): int } /** - * @return mixed - * @throws Exception\ProtocolException + * @throws \PHPinnacle\Buffer\BufferOverflow + * @throws \PHPinnacle\Ridge\Exception\ProtocolException */ - private function consumeValue() + private function consumeValue(): float|\DateTimeInterface|null|array|bool|int|string { $fieldType = $this->consumeUint8(); - switch ($fieldType) { - case Constants::FIELD_BOOLEAN: - return $this->consumeUint8() > 0; - case Constants::FIELD_SHORT_SHORT_INT: - return $this->consumeInt8(); - case Constants::FIELD_SHORT_SHORT_UINT: - return $this->consumeUint8(); - case Constants::FIELD_SHORT_INT: - return $this->consumeInt16(); - case Constants::FIELD_SHORT_UINT: - return $this->consumeUint16(); - case Constants::FIELD_LONG_INT: - return $this->consumeInt32(); - case Constants::FIELD_LONG_UINT: - return $this->consumeUint32(); - case Constants::FIELD_LONG_LONG_INT: - return $this->consumeInt64(); - case Constants::FIELD_LONG_LONG_UINT: - return $this->consumeUint64(); - case Constants::FIELD_FLOAT: - return $this->consumeFloat(); - case Constants::FIELD_DOUBLE: - return $this->consumeDouble(); - case Constants::FIELD_DECIMAL: - return $this->consumeDecimal(); - case Constants::FIELD_SHORT_STRING: - return $this->consume($this->consumeUint8()); - case Constants::FIELD_LONG_STRING: - return $this->consume($this->consumeUint32()); - case Constants::FIELD_TIMESTAMP: - return $this->consumeTimestamp(); - case Constants::FIELD_ARRAY: - return $this->consumeArray(); - case Constants::FIELD_TABLE: - return $this->consumeTable(); - case Constants::FIELD_NULL: - return null; - default: - throw Exception\ProtocolException::unknownFieldType($fieldType); - } + return match ($fieldType) { + Constants::FIELD_BOOLEAN => $this->consumeUint8() > 0, + Constants::FIELD_SHORT_SHORT_INT => $this->consumeInt8(), + Constants::FIELD_SHORT_SHORT_UINT => $this->consumeUint8(), + Constants::FIELD_SHORT_INT => $this->consumeInt16(), + Constants::FIELD_SHORT_UINT => $this->consumeUint16(), + Constants::FIELD_LONG_INT => $this->consumeInt32(), + Constants::FIELD_LONG_UINT => $this->consumeUint32(), + Constants::FIELD_LONG_LONG_INT => $this->consumeInt64(), + Constants::FIELD_LONG_LONG_UINT => $this->consumeUint64(), + Constants::FIELD_FLOAT => $this->consumeFloat(), + Constants::FIELD_DOUBLE => $this->consumeDouble(), + Constants::FIELD_DECIMAL => $this->consumeDecimal(), + Constants::FIELD_SHORT_STRING => $this->consume($this->consumeUint8()), + Constants::FIELD_LONG_STRING => $this->consume($this->consumeUint32()), + Constants::FIELD_TIMESTAMP => $this->consumeTimestamp(), + Constants::FIELD_ARRAY => $this->consumeArray(), + Constants::FIELD_TABLE => $this->consumeTable(), + Constants::FIELD_NULL => null, + default => throw Exception\ProtocolException::unknownFieldType($fieldType), + }; } /** - * @param mixed $value + * @throws \PHPinnacle\Ridge\Exception\ProtocolException */ - private function appendValue($value) + private function appendValue(mixed $value): void { if (\is_string($value)) { $this->appendUint8(Constants::FIELD_LONG_STRING); $this->appendText($value); - } elseif (\is_int($value)) { + + return; + } + + if (\is_int($value)) { $this->appendUint8(Constants::FIELD_LONG_INT); $this->appendInt32($value); - } elseif (\is_bool($value)) { + + return; + } + + if (\is_bool($value)) { $this->appendUint8(Constants::FIELD_BOOLEAN); - $this->appendUint8(\intval($value)); - } elseif (\is_float($value)) { + $this->appendUint8((int)$value); + + return; + } + + if (\is_float($value)) { $this->appendUint8(Constants::FIELD_DOUBLE); $this->appendDouble($value); - } elseif (\is_array($value)) { + + return; + } + + if (\is_array($value)) { if (\array_keys($value) === \range(0, \count($value) - 1)) { $this->appendUint8(Constants::FIELD_ARRAY); $this->appendArray($value); @@ -283,13 +254,23 @@ private function appendValue($value) $this->appendUint8(Constants::FIELD_TABLE); $this->appendTable($value); } - } elseif (\is_null($value)) { + + return; + } + + if (\is_null($value)) { $this->appendUint8(Constants::FIELD_NULL); - } elseif ($value instanceof \DateTime) { + + return; + } + + if ($value instanceof \DateTimeInterface) { $this->appendUint8(Constants::FIELD_TIMESTAMP); $this->appendTimestamp($value); - } else { - throw Exception\ProtocolException::unknownValueType($value); + + return; } + + throw Exception\ProtocolException::unknownValueType($value); } -} \ No newline at end of file +} diff --git a/src/Channel.php b/src/Channel.php index c188745..3077116 100644 --- a/src/Channel.php +++ b/src/Channel.php @@ -12,25 +12,25 @@ namespace PHPinnacle\Ridge; +use PHPinnacle\Ridge\Exception\ProtocolException; use function Amp\call; use Amp\Deferred; use Amp\Promise; final class Channel { - private const - STATE_READY = 1, - STATE_OPEN = 2, - STATE_CLOSING = 3, - STATE_CLOSED = 4, - STATE_ERROR = 5 - ; - - private const - MODE_REGULAR = 1, // Regular AMQP guarantees of published messages delivery. - MODE_TRANSACTIONAL = 2, // Messages are published after 'tx.commit'. - MODE_CONFIRM = 3 // Broker sends asynchronously 'basic.ack's for delivered messages. - ; + private const STATE_READY = 1; + private const STATE_OPEN = 2; + private const STATE_CLOSING = 3; + private const STATE_CLOSED = 4; + private const STATE_ERROR = 5; + + /** Regular AMQP guarantees of published messages delivery. */ + private const MODE_REGULAR = 1; + /** Messages are published after 'tx.commit'. */ + private const MODE_TRANSACTIONAL = 2; + /** Broker sends asynchronously 'basic.ack's for delivered messages. */ + private const MODE_CONFIRM = 3; /** * @var int @@ -77,147 +77,128 @@ final class Channel */ private $deliveryTag = 0; - /** - * @param int $id - * @param Connection $connection - * @param Properties $properties - */ public function __construct(int $id, Connection $connection, Properties $properties) { - $this->id = $id; + $this->id = $id; $this->connection = $connection; $this->properties = $properties; - $this->receiver = new MessageReceiver($this, $connection); - $this->consumer = new Consumer($this, $this->receiver); - $this->events = new Events($this, $this->receiver); + $this->receiver = new MessageReceiver($this, $connection); + $this->consumer = new Consumer($this, $this->receiver); + $this->events = new Events($this, $this->receiver); } - /** - * @return int - */ public function id(): int { return $this->id; } - /** - * @return Events - */ public function events(): Events { return $this->events; } /** - * @param string $outOfBand - * * @return Promise + * + * @throws \PHPinnacle\Ridge\Exception\ChannelException */ public function open(string $outOfBand = ''): Promise { - return call(function () use ($outOfBand) { - if ($this->state !== self::STATE_READY) { - throw Exception\ChannelException::notReady($this->id); - } + return call( + function () use ($outOfBand) { + if ($this->state !== self::STATE_READY) { + throw Exception\ChannelException::notReady($this->id); + } - yield $this->connection->write((new Buffer) - ->appendUint8(1) - ->appendUint16($this->id) - ->appendUint32(5 + \strlen($outOfBand)) - ->appendUint16(20) - ->appendUint16(10) - ->appendString($outOfBand) - ->appendUint8(206) - ); + yield $this->connection->write((new Buffer) + ->appendUint8(1) + ->appendUint16($this->id) + ->appendUint32(5 + \strlen($outOfBand)) + ->appendUint16(20) + ->appendUint16(10) + ->appendString($outOfBand) + ->appendUint8(206) + ); - yield $this->await(Protocol\ChannelOpenOkFrame::class); + yield $this->await(Protocol\ChannelOpenOkFrame::class); - $this->receiver->start(); - $this->consumer->start(); + $this->receiver->start(); + $this->consumer->start(); - $this->state = self::STATE_OPEN; - }); + $this->state = self::STATE_OPEN; + } + ); } /** - * @param int $code - * @param string $reason - * * @return Promise + * + * @throws \PHPinnacle\Ridge\Exception\ChannelException */ public function close(int $code = 0, string $reason = ''): Promise { - return call(function () use ($code, $reason) { - if ($this->state === self::STATE_CLOSED) { - throw Exception\ChannelException::alreadyClosed($this->id); - } + return call( + function () use ($code, $reason) { + if ($this->state === self::STATE_CLOSED) { + throw Exception\ChannelException::alreadyClosed($this->id); + } - if ($this->state === self::STATE_CLOSING) { - return; - } + if ($this->state === self::STATE_CLOSING) { + return; + } - $this->state = self::STATE_CLOSING; + $this->state = self::STATE_CLOSING; - $this->receiver->stop(); - $this->consumer->stop(); + $this->receiver->stop(); + $this->consumer->stop(); - yield $this->connection->write((new Buffer) - ->appendUint8(1) - ->appendUint16($this->id) - ->appendUint32(11 + \strlen($reason)) - ->appendUint16(20) - ->appendUint16(40) - ->appendInt16($code) - ->appendString($reason) - ->appendInt16(0) - ->appendInt16(0) - ->appendUint8(206) - ); + yield $this->connection->write((new Buffer) + ->appendUint8(1) + ->appendUint16($this->id) + ->appendUint32(11 + \strlen($reason)) + ->appendUint16(20) + ->appendUint16(40) + ->appendInt16($code) + ->appendString($reason) + ->appendInt16(0) + ->appendInt16(0) + ->appendUint8(206) + ); - yield $this->await(Protocol\ChannelCloseOkFrame::class); - - $this->connection->cancel($this->id); + yield $this->await(Protocol\ChannelCloseOkFrame::class); - $this->state = self::STATE_CLOSED; - }); + $this->connection->cancel($this->id); + + $this->state = self::STATE_CLOSED; + } + ); } /** - * @param int $prefetchSize - * @param int $prefetchCount - * @param bool $global - * * @return Promise */ public function qos(int $prefetchSize = 0, int $prefetchCount = 0, bool $global = false): Promise { - return call(function () use ($prefetchSize, $prefetchCount, $global) { - yield $this->connection->write((new Buffer) - ->appendUint8(1) - ->appendUint16($this->id) - ->appendUint32(11) - ->appendUint16(60) - ->appendUint16(10) - ->appendInt32($prefetchSize) - ->appendInt16($prefetchCount) - ->appendBits([$global]) - ->appendUint8(206) - ); + return call( + function () use ($prefetchSize, $prefetchCount, $global) { + yield $this->connection->write((new Buffer) + ->appendUint8(1) + ->appendUint16($this->id) + ->appendUint32(11) + ->appendUint16(60) + ->appendUint16(10) + ->appendInt32($prefetchSize) + ->appendInt16($prefetchCount) + ->appendBits([$global]) + ->appendUint8(206) + ); - yield $this->await(Protocol\BasicQosOkFrame::class); - }); + yield $this->await(Protocol\BasicQosOkFrame::class); + } + ); } /** - * @param callable $callback - * @param string $queue - * @param string $consumerTag - * @param bool $noLocal - * @param bool $noAck - * @param bool $exclusive - * @param bool $noWait - * @param array $arguments - * * @return Promise */ public function consume @@ -230,125 +211,137 @@ public function consume bool $exclusive = false, bool $noWait = false, array $arguments = [] - ) : Promise - { + ): Promise { $flags = [$noLocal, $noAck, $exclusive, $noWait]; - return call(function () use ($callback, $queue, $consumerTag, $flags, $noWait, $arguments) { - yield $this->connection->method($this->id, (new Buffer) - ->appendUint16(60) - ->appendUint16(20) - ->appendInt16(0) - ->appendString($queue) - ->appendString($consumerTag) - ->appendBits($flags) - ->appendTable($arguments) - ); - - if ($noWait === false) { - /** @var Protocol\BasicConsumeOkFrame $frame */ - $frame = yield $this->await(Protocol\BasicConsumeOkFrame::class); - - if ('' === $consumerTag) { - $consumerTag = $frame->consumerTag; + return call( + function () use ($callback, $queue, $consumerTag, $flags, $noWait, $arguments) { + yield $this->connection->method($this->id, (new Buffer) + ->appendUint16(60) + ->appendUint16(20) + ->appendInt16(0) + ->appendString($queue) + ->appendString($consumerTag) + ->appendBits($flags) + ->appendTable($arguments) + ); + + if ($noWait === false) { + /** @var Protocol\BasicConsumeOkFrame $frame */ + $frame = yield $this->await(Protocol\BasicConsumeOkFrame::class); + + if ('' === $consumerTag) { + $consumerTag = $frame->consumerTag; + } } - } - $this->consumer->subscribe($consumerTag, $callback); + $this->consumer->subscribe($consumerTag, $callback); - return $consumerTag; - }); + return $consumerTag; + } + ); } /** - * @param string $consumerTag - * @param bool $noWait - * * @return Promise */ public function cancel(string $consumerTag, bool $noWait = false): Promise { - return call(function () use ($consumerTag, $noWait) { - yield $this->connection->write((new Buffer) - ->appendUint8(1) - ->appendUint16($this->id) - ->appendUint32(6 + \strlen($consumerTag)) - ->appendUint16(60) - ->appendUint16(30) - ->appendString($consumerTag) - ->appendBits([$noWait]) - ->appendUint8(206) - ); + return call( + function () use ($consumerTag, $noWait) { + yield $this->connection->write((new Buffer) + ->appendUint8(1) + ->appendUint16($this->id) + ->appendUint32(6 + \strlen($consumerTag)) + ->appendUint16(60) + ->appendUint16(30) + ->appendString($consumerTag) + ->appendBits([$noWait]) + ->appendUint8(206) + ); - if ($noWait === false) { - yield $this->await(Protocol\BasicCancelOkFrame::class); - } + if ($noWait === false) { + yield $this->await(Protocol\BasicCancelOkFrame::class); + } - $this->consumer->cancel($consumerTag); - }); + $this->consumer->cancel($consumerTag); + } + ); } /** - * @param Message $message - * @param bool $multiple - * * @return Promise + * + * @throws \PHPinnacle\Ridge\Exception\ProtocolException */ public function ack(Message $message, bool $multiple = false): Promise { - return call(function () use ($message, $multiple) { - yield $this->connection->write((new Buffer) - ->appendUint8(1) - ->appendUint16($this->id) - ->appendUint32(13) - ->appendUint16(60) - ->appendUint16(80) - ->appendInt64($message->deliveryTag()) - ->appendBits([$multiple]) - ->appendUint8(206) - ); - }); + return call( + function () use ($message, $multiple) { + if ($message->deliveryTag === null) { + throw ProtocolException::unsupportedDeliveryTag(); + } + + yield $this->connection->write((new Buffer) + ->appendUint8(1) + ->appendUint16($this->id) + ->appendUint32(13) + ->appendUint16(60) + ->appendUint16(80) + ->appendInt64($message->deliveryTag) + ->appendBits([$multiple]) + ->appendUint8(206) + ); + } + ); } /** - * @param Message $message - * @param bool $multiple - * @param bool $requeue - * * @return Promise + * + * @throws \PHPinnacle\Ridge\Exception\ProtocolException */ public function nack(Message $message, bool $multiple = false, bool $requeue = true): Promise { - return call(function () use ($message, $multiple, $requeue) { - yield $this->connection->write((new Buffer) - ->appendUint8(1) - ->appendUint16($this->id) - ->appendUint32(13) - ->appendUint16(60) - ->appendUint16(120) - ->appendInt64($message->deliveryTag()) - ->appendBits([$multiple, $requeue]) - ->appendUint8(206) - ); - }); + return call( + function () use ($message, $multiple, $requeue) { + if ($message->deliveryTag === null) { + throw ProtocolException::unsupportedDeliveryTag(); + } + + yield $this->connection->write((new Buffer) + ->appendUint8(1) + ->appendUint16($this->id) + ->appendUint32(13) + ->appendUint16(60) + ->appendUint16(120) + ->appendInt64($message->deliveryTag) + ->appendBits([$multiple, $requeue]) + ->appendUint8(206) + ); + } + ); } /** - * @param Message $message - * @param bool $requeue - * * @return Promise + * + * @throws \PHPinnacle\Ridge\Exception\ProtocolException */ public function reject(Message $message, bool $requeue = true): Promise { return call(function () use ($message, $requeue) { + if ($message->deliveryTag === null) { + throw ProtocolException::unsupportedDeliveryTag(); + } + yield $this->connection->write((new Buffer) ->appendUint8(1) ->appendUint16($this->id) ->appendUint32(13) ->appendUint16(60) ->appendUint16(90) - ->appendInt64($message->deliveryTag()) + ->appendInt64($message->deliveryTag) ->appendBits([$requeue]) ->appendUint8(206) ); @@ -356,132 +349,104 @@ public function reject(Message $message, bool $requeue = true): Promise } /** - * @param bool $requeue - * * @return Promise */ public function recover(bool $requeue = false): Promise { - return call(function () use ($requeue) { - $this->connection->write((new Buffer) - ->appendUint8(1) - ->appendUint16($this->id) - ->appendUint32(5) - ->appendUint16(60) - ->appendUint16(110) - ->appendBits([$requeue]) - ->appendUint8(206) - ); - - yield $this->await(Protocol\BasicRecoverOkFrame::class); - }); - } + return call( + function () use ($requeue) { + $this->connection->write((new Buffer) + ->appendUint8(1) + ->appendUint16($this->id) + ->appendUint32(5) + ->appendUint16(60) + ->appendUint16(110) + ->appendBits([$requeue]) + ->appendUint8(206) + ); - /** - * @param bool $requeue - * - * @return Promise - * @deprecated This method is deprecated in favour of the synchronous Recover/Recover-Ok. - */ - public function recoverAsync(bool $requeue = false): Promise - { - return call(function () use ($requeue) { - yield $this->connection->write((new Buffer) - ->appendUint8(1) - ->appendUint16($this->id) - ->appendUint32(5) - ->appendUint16(60) - ->appendUint16(100) - ->appendBits([$requeue]) - ->appendUint8(206) - ); - }); + yield $this->await(Protocol\BasicRecoverOkFrame::class); + } + ); } /** - * @param string $queue - * @param bool $noAck - * * @return Promise */ public function get(string $queue = '', bool $noAck = false): Promise { static $getting = false; - return call(function () use ($queue, $noAck, &$getting) { - if ($getting) { - throw Exception\ChannelException::getInProgress(); - } + return call( + function () use ($queue, $noAck, &$getting) { + if ($getting) { + throw Exception\ChannelException::getInProgress(); + } - $getting = true; + $getting = true; - yield $this->connection->write((new Buffer) - ->appendUint8(1) - ->appendUint16($this->id) - ->appendUint32(8 + \strlen($queue)) - ->appendUint16(60) - ->appendUint16(70) - ->appendInt16(0) - ->appendString($queue) - ->appendBits([$noAck]) - ->appendUint8(206) - ); + yield $this->connection->write((new Buffer) + ->appendUint8(1) + ->appendUint16($this->id) + ->appendUint32(8 + \strlen($queue)) + ->appendUint16(60) + ->appendUint16(70) + ->appendInt16(0) + ->appendString($queue) + ->appendBits([$noAck]) + ->appendUint8(206) + ); - $frame = yield Promise\first([ - $this->await(Protocol\BasicGetOkFrame::class), - $this->await(Protocol\BasicGetEmptyFrame::class) - ]); + /** @var Protocol\BasicGetOkFrame|Protocol\BasicGetEmptyFrame $frame */ + $frame = yield Promise\first([ + $this->await(Protocol\BasicGetOkFrame::class), + $this->await(Protocol\BasicGetEmptyFrame::class) + ]); - if ($frame instanceof Protocol\BasicGetEmptyFrame) { - $getting = false; + if ($frame instanceof Protocol\BasicGetEmptyFrame) { + $getting = false; - return null; - } + return null; + } - /** @var Protocol\ContentHeaderFrame $header */ - $header = yield $this->await(Protocol\ContentHeaderFrame::class); + /** @var Protocol\ContentHeaderFrame $header */ + $header = yield $this->await(Protocol\ContentHeaderFrame::class); - $buffer = new Buffer; - $remaining = $header->bodySize; + $buffer = new Buffer; + $remaining = $header->bodySize; - while ($remaining > 0) { - /** @var Protocol\ContentBodyFrame $body */ - $body = yield $this->await(Protocol\ContentBodyFrame::class); + while ($remaining > 0) { + /** @var Protocol\ContentBodyFrame $body */ + $body = yield $this->await(Protocol\ContentBodyFrame::class); - $buffer->append($body->payload); + $buffer->append((string)$body->payload); - $remaining -= $body->size; + $remaining -= (int)$body->size; - if ($remaining < 0) { - $this->state = self::STATE_ERROR; + if ($remaining < 0) { + $this->state = self::STATE_ERROR; - throw Exception\ChannelException::bodyOverflow($remaining); + throw Exception\ChannelException::bodyOverflow($remaining); + } } - } - $getting = false; - - return new Message( - $buffer->flush(), - $frame->exchange, - $frame->routingKey, - null, - $frame->deliveryTag, - $frame->redelivered, - false, - $header->toArray() - ); - }); + $getting = false; + + return new Message( + $buffer->flush(), + $frame->exchange, + $frame->routingKey, + null, + $frame->deliveryTag, + $frame->redelivered, + false, + $header->toArray() + ); + } + ); } /** - * @param string $body - * @param string $exchange - * @param string $routingKey - * @param array $headers - * @param bool $mandatory - * @param bool $immediate - * * @return Promise */ public function publish @@ -492,126 +457,133 @@ public function publish array $headers = [], bool $mandatory = false, bool $immediate = false - ): Promise - { - return call(function () use ($body, $exchange, $routingKey, $headers, $mandatory, $immediate) { - yield $this->doPublish($body, $exchange, $routingKey, $headers, $mandatory, $immediate); + ): Promise { + return call( + function () use ($body, $exchange, $routingKey, $headers, $mandatory, $immediate) { + yield $this->doPublish($body, $exchange, $routingKey, $headers, $mandatory, $immediate); - return $this->mode === self::MODE_CONFIRM ? ++$this->deliveryTag : null; - }); + return $this->mode === self::MODE_CONFIRM ? ++$this->deliveryTag : null; + } + ); } /** * @return Promise + * + * @throws \PHPinnacle\Ridge\Exception\ChannelException */ public function txSelect(): Promise { - return call(function () { - if ($this->mode !== self::MODE_REGULAR) { - throw Exception\ChannelException::notRegularFor("transactional"); - } + return call( + function () { + if ($this->mode !== self::MODE_REGULAR) { + throw Exception\ChannelException::notRegularFor("transactional"); + } - yield $this->connection->write((new Buffer) - ->appendUint8(1) - ->appendUint16($this->id) - ->appendUint32(4) - ->appendUint16(90) - ->appendUint16(10) - ->appendUint8(206) - ); + yield $this->connection->write((new Buffer) + ->appendUint8(1) + ->appendUint16($this->id) + ->appendUint32(4) + ->appendUint16(90) + ->appendUint16(10) + ->appendUint8(206) + ); - yield $this->await(Protocol\TxSelectOkFrame::class); + yield $this->await(Protocol\TxSelectOkFrame::class); - $this->mode = self::MODE_TRANSACTIONAL; - }); + $this->mode = self::MODE_TRANSACTIONAL; + } + ); } /** * @return Promise + * + * @throws \PHPinnacle\Ridge\Exception\ChannelException */ public function txCommit(): Promise { - return call(function () { - if ($this->mode !== self::MODE_TRANSACTIONAL) { - throw Exception\ChannelException::notTransactional(); - } + return call( + function () { + if ($this->mode !== self::MODE_TRANSACTIONAL) { + throw Exception\ChannelException::notTransactional(); + } - yield $this->connection->write((new Buffer) - ->appendUint8(1) - ->appendUint16($this->id) - ->appendUint32(4) - ->appendUint16(90) - ->appendUint16(20) - ->appendUint8(206) - ); + yield $this->connection->write((new Buffer) + ->appendUint8(1) + ->appendUint16($this->id) + ->appendUint32(4) + ->appendUint16(90) + ->appendUint16(20) + ->appendUint8(206) + ); - yield $this->await(Protocol\TxCommitOkFrame::class); - }); + yield $this->await(Protocol\TxCommitOkFrame::class); + } + ); } /** * @return Promise + * + * @throws \PHPinnacle\Ridge\Exception\ChannelException */ public function txRollback(): Promise { - return call(function () { - if ($this->mode !== self::MODE_TRANSACTIONAL) { - throw Exception\ChannelException::notTransactional(); - } + return call( + function () { + if ($this->mode !== self::MODE_TRANSACTIONAL) { + throw Exception\ChannelException::notTransactional(); + } - yield $this->connection->write((new Buffer) - ->appendUint8(1) - ->appendUint16($this->id) - ->appendUint32(4) - ->appendUint16(90) - ->appendUint16(30) - ->appendUint8(206) - ); + yield $this->connection->write((new Buffer) + ->appendUint8(1) + ->appendUint16($this->id) + ->appendUint32(4) + ->appendUint16(90) + ->appendUint16(30) + ->appendUint8(206) + ); - yield $this->await(Protocol\TxRollbackOkFrame::class); - }); + yield $this->await(Protocol\TxRollbackOkFrame::class); + } + ); } /** - * @param bool $noWait - * * @return Promise + * + * @throws \PHPinnacle\Ridge\Exception\ChannelException */ - public function confirmSelect(bool $noWait = false) + public function confirmSelect(bool $noWait = false): Promise { - return call(function () use ($noWait) { - if ($this->mode !== self::MODE_REGULAR) { - throw Exception\ChannelException::notRegularFor("confirm"); - } + return call( + function () use ($noWait) { + if ($this->mode !== self::MODE_REGULAR) { + throw Exception\ChannelException::notRegularFor("confirm"); + } - yield $this->connection->write((new Buffer) - ->appendUint8(1) - ->appendUint16($this->id) - ->appendUint32(5) - ->appendUint16(85) - ->appendUint16(10) - ->appendBits([$noWait]) - ->appendUint8(206) - ); + yield $this->connection->write((new Buffer) + ->appendUint8(1) + ->appendUint16($this->id) + ->appendUint32(5) + ->appendUint16(85) + ->appendUint16(10) + ->appendBits([$noWait]) + ->appendUint8(206) + ); - if ($noWait === false) { - yield $this->await(Protocol\ConfirmSelectOkFrame::class); - } + if ($noWait === false) { + yield $this->await(Protocol\ConfirmSelectOkFrame::class); + } - $this->mode = self::MODE_CONFIRM; - $this->deliveryTag = 0; - }); + $this->mode = self::MODE_CONFIRM; + $this->deliveryTag = 0; + } + ); } /** - * @param string $queue - * @param bool $passive - * @param bool $durable - * @param bool $exclusive - * @param bool $autoDelete - * @param bool $noWait - * @param array $arguments - * * @return Promise */ public function queueDeclare @@ -623,38 +595,33 @@ public function queueDeclare bool $autoDelete = false, bool $noWait = false, array $arguments = [] - ): Promise - { + ): Promise { $flags = [$passive, $durable, $exclusive, $autoDelete, $noWait]; - return call(function () use ($queue, $flags, $noWait, $arguments) { - yield $this->connection->method($this->id, (new Buffer) - ->appendUint16(50) - ->appendUint16(10) - ->appendInt16(0) - ->appendString($queue) - ->appendBits($flags) - ->appendTable($arguments) - ); - - if ($noWait) { - return null; - } + return call( + function () use ($queue, $flags, $noWait, $arguments) { + yield $this->connection->method($this->id, (new Buffer) + ->appendUint16(50) + ->appendUint16(10) + ->appendInt16(0) + ->appendString($queue) + ->appendBits($flags) + ->appendTable($arguments) + ); + + if ($noWait) { + return null; + } - /** @var Protocol\QueueDeclareOkFrame $frame */ - $frame = yield $this->await(Protocol\QueueDeclareOkFrame::class); + /** @var Protocol\QueueDeclareOkFrame $frame */ + $frame = yield $this->await(Protocol\QueueDeclareOkFrame::class); - return new Queue($frame->queue, $frame->messageCount, $frame->consumerCount); - }); + return new Queue($frame->queue, $frame->messageCount, $frame->consumerCount); + } + ); } /** - * @param string $queue - * @param string $exchange - * @param string $routingKey - * @param bool $noWait - * @param array $arguments - * * @return Promise */ public function queueBind @@ -664,35 +631,30 @@ public function queueBind string $routingKey = '', bool $noWait = false, array $arguments = [] - ): Promise - { - return call(function () use ($queue, $exchange, $routingKey, $noWait, $arguments) { - yield $this->connection->method($this->id, (new Buffer) - ->appendUint16(50) - ->appendUint16(20) - ->appendInt16(0) - ->appendString($queue) - ->appendString($exchange) - ->appendString($routingKey) - ->appendBits([$noWait]) - ->appendTable($arguments) - ); + ): Promise { + return call( + function () use ($queue, $exchange, $routingKey, $noWait, $arguments) { + yield $this->connection->method($this->id, (new Buffer) + ->appendUint16(50) + ->appendUint16(20) + ->appendInt16(0) + ->appendString($queue) + ->appendString($exchange) + ->appendString($routingKey) + ->appendBits([$noWait]) + ->appendTable($arguments) + ); + + if ($noWait) { + return; + } - if ($noWait) { - return; + yield $this->await(Protocol\QueueBindOkFrame::class); } - - yield $this->await(Protocol\QueueBindOkFrame::class); - }); + ); } /** - * @param string $queue - * @param string $exchange - * @param string $routingKey - * @param bool $noWait - * @param array $arguments - * * @return Promise */ public function queueUnbind @@ -702,65 +664,60 @@ public function queueUnbind string $routingKey = '', bool $noWait = false, array $arguments = [] - ): Promise - { - return call(function () use ($queue, $exchange, $routingKey, $noWait, $arguments) { - yield $this->connection->method($this->id, (new Buffer) - ->appendUint16(50) - ->appendUint16(50) - ->appendInt16(0) - ->appendString($queue) - ->appendString($exchange) - ->appendString($routingKey) - ->appendTable($arguments) - ); + ): Promise { + return call( + function () use ($queue, $exchange, $routingKey, $noWait, $arguments) { + yield $this->connection->method($this->id, (new Buffer) + ->appendUint16(50) + ->appendUint16(50) + ->appendInt16(0) + ->appendString($queue) + ->appendString($exchange) + ->appendString($routingKey) + ->appendTable($arguments) + ); + + if ($noWait) { + return; + } - if ($noWait) { - return; + yield $this->await(Protocol\QueueUnbindOkFrame::class); } - - yield $this->await(Protocol\QueueUnbindOkFrame::class); - }); + ); } /** - * @param string $queue - * @param bool $noWait - * * @return Promise */ public function queuePurge(string $queue = '', bool $noWait = false): Promise { - return call(function () use ($queue, $noWait) { - yield $this->connection->write((new Buffer) - ->appendUint8(1) - ->appendUint16($this->id) - ->appendUint32(8 + \strlen($queue)) - ->appendUint16(50) - ->appendUint16(30) - ->appendInt16(0) - ->appendString($queue) - ->appendBits([$noWait]) - ->appendUint8(206) - ); + return call( + function () use ($queue, $noWait) { + yield $this->connection->write((new Buffer) + ->appendUint8(1) + ->appendUint16($this->id) + ->appendUint32(8 + \strlen($queue)) + ->appendUint16(50) + ->appendUint16(30) + ->appendInt16(0) + ->appendString($queue) + ->appendBits([$noWait]) + ->appendUint8(206) + ); - if ($noWait) { - return 0; - } + if ($noWait) { + return 0; + } - /** @var Protocol\QueuePurgeOkFrame $frame */ - $frame = yield $this->await(Protocol\QueuePurgeOkFrame::class); + /** @var Protocol\QueuePurgeOkFrame $frame */ + $frame = yield $this->await(Protocol\QueuePurgeOkFrame::class); - return $frame->messageCount; - }); + return $frame->messageCount; + } + ); } /** - * @param string $queue - * @param bool $ifUnused - * @param bool $ifEmpty - * @param bool $noWait - * * @return Promise */ public function queueDelete @@ -769,45 +726,37 @@ public function queueDelete bool $ifUnused = false, bool $ifEmpty = false, bool $noWait = false - ): Promise - { + ): Promise { $flags = [$ifUnused, $ifEmpty, $noWait]; - return call(function () use ($queue, $flags, $noWait) { - yield $this->connection->write((new Buffer) - ->appendUint8(1) - ->appendUint16($this->id) - ->appendUint32(8 + strlen($queue)) - ->appendUint16(50) - ->appendUint16(40) - ->appendInt16(0) - ->appendString($queue) - ->appendBits($flags) - ->appendUint8(206) - ); + return call( + function () use ($queue, $flags, $noWait) { + yield $this->connection->write((new Buffer) + ->appendUint8(1) + ->appendUint16($this->id) + ->appendUint32(8 + strlen($queue)) + ->appendUint16(50) + ->appendUint16(40) + ->appendInt16(0) + ->appendString($queue) + ->appendBits($flags) + ->appendUint8(206) + ); - if ($noWait) { - return 0; - } + if ($noWait) { + return 0; + } - /** @var Protocol\QueueDeleteOkFrame $frame */ - $frame = yield $this->await(Protocol\QueueDeleteOkFrame::class); + /** @var Protocol\QueueDeleteOkFrame $frame */ + $frame = yield $this->await(Protocol\QueueDeleteOkFrame::class); - return $frame->messageCount; - }); + return $frame->messageCount; + } + ); } /** - * @param string $exchange - * @param string $exchangeType - * @param bool $passive - * @param bool $durable - * @param bool $autoDelete - * @param bool $internal - * @param bool $noWait - * @param array $arguments - * - * @return Promise + * @return Promise */ public function exchangeDeclare ( @@ -819,36 +768,31 @@ public function exchangeDeclare bool $internal = false, bool $noWait = false, array $arguments = [] - ): Promise - { + ): Promise { $flags = [$passive, $durable, $autoDelete, $internal, $noWait]; - return call(function () use ($exchange, $exchangeType, $flags, $noWait, $arguments) { - yield $this->connection->method($this->id, (new Buffer) - ->appendUint16(40) - ->appendUint16(10) - ->appendInt16(0) - ->appendString($exchange) - ->appendString($exchangeType) - ->appendBits($flags) - ->appendTable($arguments) - ); + return call( + function () use ($exchange, $exchangeType, $flags, $noWait, $arguments) { + yield $this->connection->method($this->id, (new Buffer) + ->appendUint16(40) + ->appendUint16(10) + ->appendInt16(0) + ->appendString($exchange) + ->appendString($exchangeType) + ->appendBits($flags) + ->appendTable($arguments) + ); + + if ($noWait) { + return; + } - if ($noWait) { - return; + yield $this->await(Protocol\ExchangeDeclareOkFrame::class); } - - yield $this->await(Protocol\ExchangeDeclareOkFrame::class); - }); + ); } /** - * @param string $destination - * @param string $source - * @param string $routingKey - * @param bool $noWait - * @param array $arguments - * * @return Promise */ public function exchangeBind @@ -858,35 +802,30 @@ public function exchangeBind string $routingKey = '', bool $noWait = false, array $arguments = [] - ): Promise - { - return call(function () use ($destination, $source, $routingKey, $noWait, $arguments) { - yield $this->connection->method($this->id, (new Buffer) - ->appendUint16(40) - ->appendUint16(30) - ->appendInt16(0) - ->appendString($destination) - ->appendString($source) - ->appendString($routingKey) - ->appendBits([$noWait]) - ->appendTable($arguments) - ); + ): Promise { + return call( + function () use ($destination, $source, $routingKey, $noWait, $arguments) { + yield $this->connection->method($this->id, (new Buffer) + ->appendUint16(40) + ->appendUint16(30) + ->appendInt16(0) + ->appendString($destination) + ->appendString($source) + ->appendString($routingKey) + ->appendBits([$noWait]) + ->appendTable($arguments) + ); + + if ($noWait) { + return; + } - if ($noWait) { - return; + yield $this->await(Protocol\ExchangeBindOkFrame::class); } - - yield $this->await(Protocol\ExchangeBindOkFrame::class); - }); + ); } /** - * @param string $destination - * @param string $source - * @param string $routingKey - * @param bool $noWait - * @param array $arguments - * * @return Promise */ public function exchangeUnbind @@ -896,68 +835,57 @@ public function exchangeUnbind string $routingKey = '', bool $noWait = false, array $arguments = [] - ): Promise - { - return call(function () use ($destination, $source, $routingKey, $noWait, $arguments) { - yield $this->connection->method($this->id, (new Buffer) - ->appendUint16(40) - ->appendUint16(40) - ->appendInt16(0) - ->appendString($destination) - ->appendString($source) - ->appendString($routingKey) - ->appendBits([$noWait]) - ->appendTable($arguments) - ); + ): Promise { + return call( + function () use ($destination, $source, $routingKey, $noWait, $arguments) { + yield $this->connection->method($this->id, (new Buffer) + ->appendUint16(40) + ->appendUint16(40) + ->appendInt16(0) + ->appendString($destination) + ->appendString($source) + ->appendString($routingKey) + ->appendBits([$noWait]) + ->appendTable($arguments) + ); + + if ($noWait) { + return; + } - if ($noWait) { - return; + yield $this->await(Protocol\ExchangeUnbindOkFrame::class); } - - yield $this->await(Protocol\ExchangeUnbindOkFrame::class); - }); + ); } /** - * @param string $exchange - * @param bool $unused - * @param bool $noWait - * * @return Promise */ public function exchangeDelete(string $exchange, bool $unused = false, bool $noWait = false): Promise { - return call(function () use ($exchange, $unused, $noWait) { - yield $this->connection->write((new Buffer) - ->appendUint8(1) - ->appendUint16($this->id) - ->appendUint32(8 + \strlen($exchange)) - ->appendUint16(40) - ->appendUint16(20) - ->appendInt16(0) - ->appendString($exchange) - ->appendBits([$unused, $noWait]) - ->appendUint8(206) - ); + return call( + function () use ($exchange, $unused, $noWait) { + yield $this->connection->write((new Buffer) + ->appendUint8(1) + ->appendUint16($this->id) + ->appendUint32(8 + \strlen($exchange)) + ->appendUint16(40) + ->appendUint16(20) + ->appendInt16(0) + ->appendString($exchange) + ->appendBits([$unused, $noWait]) + ->appendUint8(206) + ); - if ($noWait) { - return; - } + if ($noWait) { + return; + } - yield $this->await(Protocol\ExchangeDeleteOkFrame::class); - }); + yield $this->await(Protocol\ExchangeDeleteOkFrame::class); + } + ); } - /** - * @param string $body - * @param string $exchange - * @param string $routingKey - * @param array $headers - * @param bool $mandatory - * @param bool $immediate - * - * @return Promise - */ public function doPublish ( string $body, @@ -966,8 +894,7 @@ public function doPublish array $headers = [], bool $mandatory = false, bool $immediate = false - ): Promise - { + ): Promise { $flags = 0; $contentType = ''; $contentEncoding = ''; @@ -997,99 +924,111 @@ public function doPublish ->appendString($exchange) ->appendString($routingKey) ->appendBits([$mandatory, $immediate]) - ->appendUint8(206) - ; + ->appendUint8(206); $size = 14; if (isset($headers['content-type'])) { $flags |= 32768; - $contentType = $headers['content-type']; + $contentType = (string)$headers['content-type']; $size += 1 + \strlen($contentType); + unset($headers['content-type']); } if (isset($headers['content-encoding'])) { $flags |= 16384; - $contentEncoding = $headers['content-encoding']; + $contentEncoding = (string)$headers['content-encoding']; $size += 1 + \strlen($contentEncoding); + unset($headers['content-encoding']); } if (isset($headers['delivery-mode'])) { $flags |= 4096; - $deliveryMode = (int) $headers['delivery-mode']; - $size += 1; + $deliveryMode = (int)$headers['delivery-mode']; + ++$size; + unset($headers['delivery-mode']); } if (isset($headers['priority'])) { $flags |= 2048; - $priority = (int) $headers['priority']; - $size += 1; + $priority = (int)$headers['priority']; + ++$size; + unset($headers['priority']); } if (isset($headers['correlation-id'])) { $flags |= 1024; - $correlationId = $headers['correlation-id']; + $correlationId = (string)$headers['correlation-id']; $size += 1 + \strlen($correlationId); + unset($headers['correlation-id']); } if (isset($headers['reply-to'])) { $flags |= 512; - $replyTo = $headers['reply-to']; + $replyTo = (string)$headers['reply-to']; $size += 1 + \strlen($replyTo); + unset($headers['reply-to']); } if (isset($headers['expiration'])) { $flags |= 256; - $expiration = $headers['expiration']; + $expiration = (string)$headers['expiration']; $size += 1 + \strlen($expiration); + unset($headers['expiration']); } if (isset($headers['message-id'])) { $flags |= 128; - $messageId = $headers['message-id']; + $messageId = (string)$headers['message-id']; $size += 1 + \strlen($messageId); + unset($headers['message-id']); } if (isset($headers['timestamp'])) { $flags |= 64; - $timestamp = $headers['timestamp']; + $timestamp = (int)$headers['timestamp']; $size += 8; + unset($headers['timestamp']); } if (isset($headers['type'])) { $flags |= 32; - $type = $headers['type']; + $type = (string)$headers['type']; $size += 1 + \strlen($type); + unset($headers['type']); } if (isset($headers['user-id'])) { $flags |= 16; - $userId = $headers['user-id']; + $userId = (string)$headers['user-id']; $size += 1 + \strlen($userId); + unset($headers['user-id']); } if (isset($headers['app-id'])) { $flags |= 8; - $appId = $headers['app-id']; + $appId = (string)$headers['app-id']; $size += 1 + \strlen($appId); + unset($headers['app-id']); } if (isset($headers['cluster-id'])) { $flags |= 4; - $clusterId = $headers['cluster-id']; + $clusterId = (string)$headers['cluster-id']; $size += 1 + \strlen($clusterId); + unset($headers['cluster-id']); } @@ -1107,8 +1046,7 @@ public function doPublish ->appendUint16(60) ->appendUint16(0) ->appendUint64(\strlen($body)) - ->appendUint16($flags) - ; + ->appendUint16($flags); if ($flags & 32768) { $buffer->appendString($contentType); @@ -1118,15 +1056,15 @@ public function doPublish $buffer->appendString($contentEncoding); } - if ($flags & 8192) { + if ($flags & 8192 && $headersBuffer !== null) { $buffer->append($headersBuffer); } - if ($flags & 4096) { + if ($flags & 4096 && $deliveryMode !== null) { $buffer->appendUint8($deliveryMode); } - if ($flags & 2048) { + if ($flags & 2048 && $priority !== null) { $buffer->appendUint8($priority); } @@ -1146,8 +1084,9 @@ public function doPublish $buffer->appendString($messageId); } - if ($flags & 64) { - $buffer->appendTimestamp($timestamp); + if ($flags & 64 && $timestamp !== null) { + /** @noinspection PhpUnhandledExceptionInspection */ + $buffer->appendTimestamp(new \DateTimeImmutable(\sprintf('@%s', $timestamp))); } if ($flags & 32) { @@ -1171,34 +1110,44 @@ public function doPublish if (!empty($body)) { $chunks = \str_split($body, $this->properties->maxFrame()); - foreach ($chunks as $chunk) { - $buffer - ->appendUint8(3) - ->appendUint16($this->id) - ->appendUint32(\strlen($chunk)) - ->append($chunk) - ->appendUint8(206) - ; + if ($chunks !== false) { + foreach ($chunks as $chunk) { + $buffer + ->appendUint8(3) + ->appendUint16($this->id) + ->appendUint32(\strlen($chunk)) + ->append($chunk) + ->appendUint8(206); + } } } return $this->connection->write($buffer); } - + /** - * @param string $frame + * @template T + * @psalm-param class-string $frame + * @psalm-return Promise * * @return Promise */ private function await(string $frame): Promise { + /** @psalm-var Deferred $deferred */ $deferred = new Deferred; - $this->connection->subscribe($this->id, $frame, function (Protocol\AbstractFrame $frame) use ($deferred) { - $deferred->resolve($frame); + /** @psalm-var class-string $frame */ - return true; - }); + $this->connection->subscribe( + $this->id, + $frame, + static function (Protocol\AbstractFrame $frame) use ($deferred) { + $deferred->resolve($frame); + + return true; + } + ); return $deferred->promise(); } diff --git a/src/Client.php b/src/Client.php index 63f7555..9d135de 100644 --- a/src/Client.php +++ b/src/Client.php @@ -19,12 +19,10 @@ final class Client { - private const - STATE_NOT_CONNECTED = 0, - STATE_CONNECTING = 1, - STATE_CONNECTED = 2, - STATE_DISCONNECTING = 3 - ; + private const STATE_NOT_CONNECTED = 0; + private const STATE_CONNECTING = 1; + private const STATE_CONNECTED = 2; + private const STATE_DISCONNECTING = 3; /** * @var Config @@ -56,26 +54,18 @@ final class Client */ private $properties; - /** - * @param Config $config - */ public function __construct(Config $config) { $this->config = $config; } - /** - * @param string $dsn - * - * @return self - */ public static function create(string $dsn): self { return new self(Config::parse($dsn)); } /** - * @return Properties + * @throws \PHPinnacle\Ridge\Exception\ClientException */ public function properties(): Properties { @@ -88,153 +78,157 @@ public function properties(): Properties /** * @return Promise + * + * @throws \PHPinnacle\Ridge\Exception\ClientException */ public function connect(): Promise { - return call(function () { - if ($this->state !== self::STATE_NOT_CONNECTED) { - throw Exception\ClientException::alreadyConnected(); - } - - $this->state = self::STATE_CONNECTING; + return call( + function () { + if ($this->state !== self::STATE_NOT_CONNECTED) { + throw Exception\ClientException::alreadyConnected(); + } - $this->connection = new Connection($this->config->uri()); + $this->state = self::STATE_CONNECTING; - $timeout = $this->config->timeout() * 1000; + $this->connection = new Connection($this->config->uri()); - yield $this->connection->open( - $timeout, - $this->config->tcpAttempts(), - $this->config->tcpNoDelay() - ); + yield $this->connection->open( + $this->config->timeout, + $this->config->tcpAttempts, + $this->config->tcpNoDelay + ); - $buffer = new Buffer; - $buffer - ->append('AMQP') - ->appendUint8(0) - ->appendUint8(0) - ->appendUint8(9) - ->appendUint8(1) - ; + $buffer = new Buffer; + $buffer + ->append('AMQP') + ->appendUint8(0) + ->appendUint8(0) + ->appendUint8(9) + ->appendUint8(1); - yield $this->connection->write($buffer); + yield $this->connection->write($buffer); - yield $this->connectionStart(); - yield $this->connectionTune(); - yield $this->connectionOpen(); + yield $this->connectionStart(); + yield $this->connectionTune(); + yield $this->connectionOpen(); - asyncCall(function () { - yield $this->await(Protocol\ConnectionCloseFrame::class); + asyncCall( + function () { + yield $this->await(Protocol\ConnectionCloseFrame::class); - $buffer = new Buffer; - $buffer - ->appendUint8(1) - ->appendUint16(0) - ->appendUint32(4) - ->appendUint16(10) - ->appendUint16(51) - ->appendUint8(206) - ; + $buffer = new Buffer; + $buffer + ->appendUint8(1) + ->appendUint16(0) + ->appendUint32(4) + ->appendUint16(10) + ->appendUint16(51) + ->appendUint8(206); - $this->connection->write($buffer); - $this->connection->close(); - }); + $this->connection->write($buffer); + $this->connection->close(); + } + ); - $this->state = self::STATE_CONNECTED; - }); + $this->state = self::STATE_CONNECTED; + } + ); } /** - * @param int $code - * @param string $reason - * * @return Promise + * + * @throws \PHPinnacle\Ridge\Exception\ClientException */ public function disconnect(int $code = 0, string $reason = ''): Promise { - return call(function() use ($code, $reason) { - if (\in_array($this->state, [self::STATE_NOT_CONNECTED, self::STATE_DISCONNECTING])) { - return; - } + return call( + function () use ($code, $reason) { + if (\in_array($this->state, [self::STATE_NOT_CONNECTED, self::STATE_DISCONNECTING])) { + return; + } - if ($this->state !== self::STATE_CONNECTED) { - throw Exception\ClientException::notConnected(); - } + if ($this->state !== self::STATE_CONNECTED) { + throw Exception\ClientException::notConnected(); + } - $this->state = self::STATE_DISCONNECTING; + $this->state = self::STATE_DISCONNECTING; - if ($code === 0) { - $promises = []; + if ($code === 0) { + $promises = []; - foreach($this->channels as $id => $channel) { - $promises[] = $channel->close($code, $reason); - } + foreach ($this->channels as $id => $channel) { + $promises[] = $channel->close($code, $reason); + } - yield $promises; - } + yield $promises; + } - yield $this->connectionClose($code, $reason); + yield $this->connectionClose($code, $reason); - $this->connection->close(); + $this->connection->close(); - $this->state = self::STATE_NOT_CONNECTED; - }); + $this->state = self::STATE_NOT_CONNECTED; + } + ); } /** * @return Promise + * + * @throws \PHPinnacle\Ridge\Exception\ClientException */ public function channel(): Promise { - return call(function() { - if ($this->state !== self::STATE_CONNECTED) { - throw Exception\ClientException::notConnected(); - } + return call( + function () { + if ($this->state !== self::STATE_CONNECTED) { + throw Exception\ClientException::notConnected(); + } - try { - $id = $this->findChannelId(); - $channel = new Channel($id, $this->connection, $this->properties); + try { + $id = $this->findChannelId(); + $channel = new Channel($id, $this->connection, $this->properties); - $this->channels[$id] = $channel; + $this->channels[$id] = $channel; - yield $channel->open(); - yield $channel->qos($this->config->qosSize(), $this->config->qosCount(), $this->config->qosGlobal()); + yield $channel->open(); + yield $channel->qos($this->config->qosSize, $this->config->qosCount, $this->config->qosGlobal); - asyncCall(function () use ($id) { - $frame = yield Promise\first([ - $this->await(Protocol\ChannelCloseFrame::class, $id), - $this->await(Protocol\ChannelCloseOkFrame::class, $id) - ]); + asyncCall(function () use ($id) { + /** @var Protocol\ChannelCloseFrame|Protocol\ChannelCloseOkFrame $frame */ + $frame = yield Promise\first([ + $this->await(Protocol\ChannelCloseFrame::class, $id), + $this->await(Protocol\ChannelCloseOkFrame::class, $id) + ]); - $this->connection->cancel($id); + $this->connection->cancel($id); - if ($frame instanceof Protocol\ChannelCloseFrame) { - $buffer = new Buffer; - $buffer - ->appendUint8(1) - ->appendUint16($id) - ->appendUint32(4) - ->appendUint16(20) - ->appendUint16(41) - ->appendUint8(206) - ; + if ($frame instanceof Protocol\ChannelCloseFrame) { + $buffer = new Buffer; + $buffer + ->appendUint8(1) + ->appendUint16($id) + ->appendUint32(4) + ->appendUint16(20) + ->appendUint16(41) + ->appendUint8(206); - yield $this->connection->write($buffer); - } + yield $this->connection->write($buffer); + } - unset($this->channels[$id]); - }); + unset($this->channels[$id]); + }); - return $channel; - } catch (\Throwable $error) { - throw Exception\ClientException::unexpectedResponse($error); + return $channel; + } catch (\Throwable $error) { + throw Exception\ClientException::unexpectedResponse($error); + } } - }); + ); } - /** - * @return bool - */ public function isConnected(): bool { return $this->state === self::STATE_CONNECTED; @@ -242,40 +236,42 @@ public function isConnected(): bool /** * @return Promise + * + * @throws \PHPinnacle\Ridge\Exception\ClientException */ private function connectionStart(): Promise { - return call(function () { - /** @var Protocol\ConnectionStartFrame $start */ - $start = yield $this->await(Protocol\ConnectionStartFrame::class); + return call( + function () { + /** @var Protocol\ConnectionStartFrame $start */ + $start = yield $this->await(Protocol\ConnectionStartFrame::class); - if (\strpos($start->mechanisms, "AMQPLAIN") === false) { - throw Exception\ClientException::notSupported($start->mechanisms); - } + if (!\str_contains($start->mechanisms, 'AMQPLAIN')) { + throw Exception\ClientException::notSupported($start->mechanisms); + } + + $this->properties = Properties::create($start->serverProperties); + + $buffer = new Buffer; + $buffer + ->appendTable([ + 'LOGIN' => $this->config->user, + 'PASSWORD' => $this->config->pass, + ]) + ->discard(4); + + $frameBuffer = new Buffer; + $frameBuffer + ->appendUint16(10) + ->appendUint16(11) + ->appendTable([]) + ->appendString('AMQPLAIN') + ->appendText((string)$buffer) + ->appendString('en_US'); - $this->properties = Properties::create($start->serverProperties); - - $buffer = new Buffer; - $buffer - ->appendTable([ - "LOGIN" => $this->config->user(), - "PASSWORD" => $this->config->password(), - ]) - ->discard(4) - ; - - $frameBuffer = new Buffer; - $frameBuffer - ->appendUint16(10) - ->appendUint16(11) - ->appendTable([]) - ->appendString("AMQPLAIN") - ->appendText((string) $buffer) - ->appendString("en_US") - ; - - return $this->connection->method(0, $frameBuffer); - }); + return $this->connection->method(0, $frameBuffer); + } + ); } /** @@ -283,39 +279,41 @@ private function connectionStart(): Promise */ private function connectionTune(): Promise { - return call(function () { - /** @var Protocol\ConnectionTuneFrame $tune */ - $tune = yield $this->await(Protocol\ConnectionTuneFrame::class); + return call( + function () { + /** @var Protocol\ConnectionTuneFrame $tune */ + $tune = yield $this->await(Protocol\ConnectionTuneFrame::class); - $heartbeat = $this->config->heartbeat(); + $heartbeatInterval = $this->config->heartbeat; - if ($heartbeat !== 0) { - $heartbeat = \min($heartbeat, $tune->heartbeat); - } + if ($heartbeatInterval !== 0) { + $heartbeatInterval = \min($heartbeatInterval, $tune->heartbeat); + } - $maxChannel = \min($this->config->maxChannel(), $tune->channelMax); - $maxFrame = \min($this->config->maxFrame(), $tune->frameMax); + $maxChannel = \min($this->config->maxChannel, $tune->channelMax); + $maxFrame = \min($this->config->maxFrame, $tune->frameMax); - $buffer = new Buffer; - $buffer - ->appendUint8(1) - ->appendUint16(0) - ->appendUint32(12) - ->appendUint16(10) - ->appendUint16(31) - ->appendInt16($maxChannel) - ->appendInt32($maxFrame) - ->appendInt16($heartbeat) - ->appendUint8(206); + $buffer = new Buffer; + $buffer + ->appendUint8(1) + ->appendUint16(0) + ->appendUint32(12) + ->appendUint16(10) + ->appendUint16(31) + ->appendInt16($maxChannel) + ->appendInt32($maxFrame) + ->appendInt16($heartbeatInterval) + ->appendUint8(206); - yield $this->connection->write($buffer); + yield $this->connection->write($buffer); - $this->properties->tune($maxChannel, $maxFrame); + $this->properties->tune($maxChannel, $maxFrame); - if ($heartbeat > 0) { - $this->connection->heartbeat($heartbeat); + if ($heartbeatInterval > 0) { + $this->connection->heartbeat($heartbeatInterval); + } } - }); + ); } /** @@ -323,57 +321,56 @@ private function connectionTune(): Promise */ private function connectionOpen(): Promise { - return call(function () { - $vhost = $this->config->vhost(); - $capabilities = ''; - $insist = false; - - $buffer = new Buffer; - $buffer - ->appendUint8(1) - ->appendUint16(0) - ->appendUint32(7 + \strlen($vhost) + \strlen($capabilities)) - ->appendUint16(10) - ->appendUint16(40) - ->appendString($vhost) - ->appendString($capabilities) // TODO: process server capabilities - ->appendBits([$insist]) - ->appendUint8(206) - ; - - yield $this->connection->write($buffer); - - return $this->await(Protocol\ConnectionOpenOkFrame::class); - }); + return call( + function () { + $vhost = $this->config->vhost; + $capabilities = ''; + $insist = false; + + $buffer = new Buffer; + $buffer + ->appendUint8(1) + ->appendUint16(0) + ->appendUint32(7 + \strlen($vhost) + \strlen($capabilities)) + ->appendUint16(10) + ->appendUint16(40) + ->appendString($vhost) + ->appendString($capabilities) // TODO: process server capabilities + ->appendBits([$insist]) + ->appendUint8(206); + + yield $this->connection->write($buffer); + + return $this->await(Protocol\ConnectionOpenOkFrame::class); + } + ); } /** - * @param int $code - * @param string $reason - * * @return Promise */ private function connectionClose(int $code, string $reason): Promise { - return call(function () use ($code, $reason) { - $buffer = new Buffer; - $buffer - ->appendUint8(1) - ->appendUint16(0) - ->appendUint32(11 + \strlen($reason)) - ->appendUint16(10) - ->appendUint16(50) - ->appendInt16($code) - ->appendString($reason) - ->appendInt16(0) - ->appendInt16(0) - ->appendUint8(206) - ; - - yield $this->connection->write($buffer); - - return $this->await(Protocol\ConnectionCloseOkFrame::class); - }); + return call( + function () use ($code, $reason) { + $buffer = new Buffer; + $buffer + ->appendUint8(1) + ->appendUint16(0) + ->appendUint32(11 + \strlen($reason)) + ->appendUint16(10) + ->appendUint16(50) + ->appendInt16($code) + ->appendString($reason) + ->appendInt16(0) + ->appendInt16(0) + ->appendUint8(206); + + yield $this->connection->write($buffer); + + return $this->await(Protocol\ConnectionCloseOkFrame::class); + } + ); } /** @@ -381,8 +378,8 @@ private function connectionClose(int $code, string $reason): Promise */ private function findChannelId(): int { - // first check in range [next, max] ... - for ($id = $this->nextChannelId; $id <= $this->config->maxChannel(); ++$id) { + /** first check in range [next, max] ... */ + for ($id = $this->nextChannelId; $id <= $this->config->maxChannel; ++$id) { if (!isset($this->channels[$id])) { $this->nextChannelId = $id + 1; @@ -390,7 +387,7 @@ private function findChannelId(): int } } - // then check in range [min, next) ... + /** then check in range [min, next) ... */ for ($id = 1; $id < $this->nextChannelId; ++$id) { if (!isset($this->channels[$id])) { $this->nextChannelId = $id + 1; @@ -403,20 +400,26 @@ private function findChannelId(): int } /** - * @param string $frame - * @param int $channel - * - * @return Promise + * @template T + * @psalm-param class-string $frame + * @psalm-return Promise */ private function await(string $frame, int $channel = 0): Promise { + /** @psalm-var Deferred $deferred */ $deferred = new Deferred; - $this->connection->subscribe($channel, $frame, function (Protocol\AbstractFrame $frame) use ($deferred) { - $deferred->resolve($frame); + /** @psalm-var class-string $frame */ - return true; - }); + $this->connection->subscribe( + $channel, + $frame, + static function (Protocol\AbstractFrame $frame) use ($deferred) { + $deferred->resolve($frame); + + return true; + } + ); return $deferred->promise(); } diff --git a/src/Config.php b/src/Config.php index 65c66db..00f6f6c 100644 --- a/src/Config.php +++ b/src/Config.php @@ -12,105 +12,90 @@ namespace PHPinnacle\Ridge; +use PHPinnacle\Ridge\Exception\ConfigurationException; + final class Config { - private const - DEFAULT_HOST = 'localhost', - DEFAULT_PORT = 5672, - DEFAULT_VHOST = '/', - DEFAULT_USER = 'guest', - DEFAULT_PASS = 'guest' - ; - - private const OPTIONS = [ - 'timeout' => 1000, - 'heartbeat' => 1000, - 'qos_count' => 0, - 'qos_size' => 0, - 'qos_global' => false, - 'tcp_nodelay' => false, - 'tcp_attempts' => 2, - 'max_frame' => 0xFFFF, - 'max_channel' => 0xFFFF, - ]; + private const DEFAULT_HOST = 'localhost'; + private const DEFAULT_PORT = 5672; + private const DEFAULT_VHOST = '/'; + private const DEFAULT_USER = 'guest'; + private const DEFAULT_PASS = 'guest'; /** * @var string */ - private $host; + public $host; /** * @var int */ - private $port; + public $port; /** * @var string */ - private $user; + public $user; /** * @var string */ - private $pass; + public $pass; /** * @var string */ - private $vhost; + public $vhost; /** + * Connection timeout (in milliseconds) + * * @var int */ - private $timeout = 1; + public $timeout = 1000; /** + * Heartbeat interval (in milliseconds) + * * @var int */ - private $heartbeat = 60; + public $heartbeat = 60000; /** * @var int */ - private $qosSize = 0; + public $qosSize = 0; /** * @var int */ - private $qosCount = 0; + public $qosCount = 0; /** * @var bool */ - private $qosGlobal = false; + public $qosGlobal = false; /** * @var bool */ - private $tcpNoDelay = false; + public $tcpNoDelay = false; /** * @var int */ - private $tcpAttempts = 2; + public $tcpAttempts = 2; /** * @var int */ - private $maxChannel = 0xFFFF; + public $maxChannel = 0xFFFF; /** * @var int */ - private $maxFrame = 0xFFFF; + public $maxFrame = 0xFFFF; - /** - * @param string $host - * @param int $port - * @param string $user - * @param string $pass - * @param string $vhost - */ public function __construct( string $host = self::DEFAULT_HOST, int $port = self::DEFAULT_PORT, @@ -118,28 +103,37 @@ public function __construct( string $pass = self::DEFAULT_PASS, string $vhost = null ) { - $this->host = $host; - $this->port = $port; - $this->user = $user; - $this->pass = $pass; + $this->host = $host; + $this->port = $port; + $this->user = $user; + $this->pass = $pass; $this->vhost = $vhost ?: self::DEFAULT_VHOST; } /** - * @param string $dsn - * - * @return self + * @throws \PHPinnacle\Ridge\Exception\ConfigurationException */ public static function parse(string $dsn): self { + if ($dsn === '') { + throw ConfigurationException::emptyDSN(); + } + $parts = \parse_url($dsn); - \parse_str($parts['query'] ?? '', $query); + if ($parts === false) { + throw ConfigurationException::incorrectDSN($dsn); + } + + \parse_str($parts['query'] ?? '', $options); - $options = \array_replace(self::OPTIONS, $query); + if (isset($parts['path']) && $parts['path'] !== '') { + /** @var string|false $vhost */ + $vhost = \substr($parts['path'], 1); - if (!empty($parts['path'])) { - $parts['path'] = \substr($parts['path'], 1); + if ($vhost !== false) { + $parts['path'] = $vhost; + } } $self = new self( @@ -147,160 +141,50 @@ public static function parse(string $dsn): self $parts['port'] ?? self::DEFAULT_PORT, $parts['user'] ?? self::DEFAULT_USER, $parts['pass'] ?? self::DEFAULT_PASS, - $parts['path'] ?? self::DEFAULT_VHOST + $parts['path'] ?? self::DEFAULT_VHOST, ); - $self->timeout = \filter_var($options['timeout'], FILTER_VALIDATE_INT); - $self->heartbeat = \filter_var($options['heartbeat'], FILTER_VALIDATE_INT); - - $self->maxFrame = \filter_var($options['max_frame'], FILTER_VALIDATE_INT); - $self->maxChannel = \filter_var($options['max_channel'], FILTER_VALIDATE_INT); - - $self->qosSize = \filter_var($options['qos_size'], FILTER_VALIDATE_INT); - $self->qosCount = \filter_var($options['qos_count'], FILTER_VALIDATE_INT); - $self->qosGlobal = \filter_var($options['qos_global'], FILTER_VALIDATE_BOOLEAN); - - $self->tcpNoDelay = \filter_var($options['tcp_nodelay'], FILTER_VALIDATE_BOOLEAN); - $self->tcpAttempts = \filter_var($options['tcp_attempts'], FILTER_VALIDATE_INT); - - return $self; - } - - /** - * @return string - */ - public function uri(): string - { - return \sprintf('tcp://%s:%d', $this->host, $this->port); - } - - /** - * @return string - */ - public function host(): string - { - return $this->host; - } - - /** - * @return int - */ - public function port(): int - { - return $this->port; - } - - /** - * @return string - */ - public function vhost(): string - { - return $this->vhost; - } - - /** - * @return string - */ - public function user(): string - { - return $this->user; - } + if (isset($options['timeout'])) { + $self->timeout = (int)$options['timeout']; + } - /** - * @return string - */ - public function password(): string - { - return $this->pass; - } + if (isset($options['heartbeat'])) { + $self->heartbeat = (int)$options['heartbeat']; + } - /** - * @param int|null $value - * - * @return int - */ - public function timeout(int $value = null): int - { - return \is_null($value) ? $this->timeout : $this->timeout = $value; - } + if (isset($options['max_frame'])) { + $self->maxFrame = (int)$options['max_frame']; + } - /** - * @param int|null $value - * - * @return int - */ - public function heartbeat(int $value = null): int - { - return \is_null($value) ? $this->heartbeat : $this->heartbeat = $value; - } + if (isset($options['max_channel'])) { + $self->maxChannel = (int)$options['max_channel']; + } - /** - * @param int|null $value - * - * @return int - */ - public function qosSize(int $value = null): int - { - return \is_null($value) ? $this->qosSize : $this->qosSize = $value; - } + if (isset($options['qos_size'])) { + $self->qosSize = (int)$options['qos_size']; + } - /** - * @param int|null $value - * - * @return int - */ - public function qosCount(int $value = null): int - { - return \is_null($value) ? $this->qosCount : $this->qosCount = $value; - } + if (isset($options['qos_count'])) { + $self->qosCount = (int)$options['qos_count']; + } - /** - * @param bool|null $value - * - * @return bool - */ - public function qosGlobal(bool $value = null): bool - { - return \is_null($value) ? $this->qosGlobal : $this->qosGlobal = $value; - } + if (isset($options['qos_global'])) { + $self->qosGlobal = (bool)$options['qos_global']; + } - /** - * @param bool|null $value - * - * @return bool - */ - public function tcpNoDelay(bool $value = null): bool - { - return \is_null($value) ? $this->tcpNoDelay : $this->tcpNoDelay = $value; - } + if (isset($options['tcp_nodelay'])) { + $self->tcpNoDelay = (bool)$options['tcp_nodelay']; + } - /** - * @param int|null $value - * - * @return int - */ - public function tcpAttempts(int $value = null): int - { - return \is_null($value) ? $this->tcpAttempts : $this->tcpAttempts = $value; - } + if (isset($options['tcp_attempts'])) { + $self->tcpAttempts = (int)$options['tcp_attempts']; + } - /** - * @param int|null $value - * - * @return int - */ - public function maxChannel(int $value = null): int - { - return \is_null($value) ? $this->maxChannel : $this->maxChannel = $value; + return $self; } - /** - * @param int|null $value - * - * @return int - */ - public function maxFrame(int $value = null): int + public function uri(): string { - return \is_null($value) ? $this->maxFrame : $this->maxFrame = $value; + return \sprintf('tcp://%s:%d', $this->host, $this->port); } } diff --git a/src/Connection.php b/src/Connection.php index f225287..7b4b3a1 100644 --- a/src/Connection.php +++ b/src/Connection.php @@ -12,12 +12,13 @@ namespace PHPinnacle\Ridge; +use PHPinnacle\Ridge\Exception\ConnectionException; use function Amp\asyncCall, Amp\call, Amp\Socket\connect; use Amp\Socket\ConnectContext; -use Amp\Deferred; use Amp\Loop; use Amp\Promise; use Amp\Socket\Socket; +use PHPinnacle\Ridge\Protocol\AbstractFrame; final class Connection { @@ -37,7 +38,8 @@ final class Connection private $socket; /** - * @var Deferred[][][] + * @var callable[][][] + * @psalm-var array, array>> */ private $callbacks = []; @@ -47,39 +49,36 @@ final class Connection private $lastWrite = 0; /** - * @var string + * @var string|null */ - private $heartbeat; + private $heartbeatWatcherId; - /** - * @param string $uri - */ public function __construct(string $uri) { - $this->uri = $uri; + $this->uri = $uri; $this->parser = new Parser; } /** - * @noinspection PhpDocMissingThrowsInspection - * - * @param Buffer $payload - * - * @return Promise + * @throws \PHPinnacle\Ridge\Exception\ConnectionException */ public function write(Buffer $payload): Promise { $this->lastWrite = Loop::now(); - /** @noinspection PhpUnhandledExceptionInspection */ - return $this->socket->write($payload->flush()); + if ($this->socket !== null) { + try { + return $this->socket->write($payload->flush()); + } catch (\Throwable $throwable) { + throw ConnectionException::writeFailed($throwable); + } + } + + throw ConnectionException::socketClosed(); } /** - * @param int $channel - * @param Buffer $payload - * - * @return Promise + * @throws \PHPinnacle\Ridge\Exception\ConnectionException */ public function method(int $channel, Buffer $payload): Promise { @@ -93,119 +92,116 @@ public function method(int $channel, Buffer $payload): Promise } /** - * @param int $channel - * @param string $frame - * @param callable $callback + * @psalm-param class-string $frame */ public function subscribe(int $channel, string $frame, callable $callback): void { $this->callbacks[$channel][$frame][] = $callback; } - /** - * @param int $channel - * - * @return void - */ public function cancel(int $channel): void { unset($this->callbacks[$channel]); } /** - * @param int $timeout - * @param int $maxAttempts - * @param bool $noDelay - * - * @return Promise + * @throws \PHPinnacle\Ridge\Exception\ConnectionException */ public function open(int $timeout, int $maxAttempts, bool $noDelay): Promise { - return call(function () use ($timeout, $maxAttempts, $noDelay) { - $context = new ConnectContext(); + return call( + function () use ($timeout, $maxAttempts, $noDelay) { + $context = new ConnectContext(); - if ($maxAttempts > 0) { - $context = $context->withMaxAttempts($maxAttempts); - } + if ($maxAttempts > 0) { + $context = $context->withMaxAttempts($maxAttempts); + } - if ($timeout > 0) { - $context = $context->withConnectTimeout($timeout); - } + if ($timeout > 0) { + $context = $context->withConnectTimeout($timeout); + } - if ($noDelay) { - $context = $context->withTcpNoDelay(); - } + if ($noDelay) { + $context = $context->withTcpNoDelay(); + } + + $this->socket = yield connect($this->uri, $context); + + asyncCall( + function () { + if ($this->socket === null) { + throw ConnectionException::socketClosed(); + } - $this->socket = yield connect($this->uri, $context); + while (null !== $chunk = yield $this->socket->read()) { + $this->parser->append($chunk); - asyncCall(function () { - while (null !== $chunk = yield $this->socket->read()) { - $this->parser->append($chunk); + while ($frame = $this->parser->parse()) { + /** @var AbstractFrame $frame */ - while ($frame = $this->parser->parse()) { - $class = \get_class($frame); + $class = \get_class($frame); - foreach ($this->callbacks[$frame->channel][$class] ?? [] as $i => $callback) { - if (yield call($callback, $frame)) { - unset($this->callbacks[$frame->channel][$class][$i]); + /** + * @psalm-var int $i + * @psalm-var callable(AbstractFrame):Promise $callback + */ + foreach ($this->callbacks[(int)$frame->channel][$class] ?? [] as $i => $callback) { + if (yield call($callback, $frame)) { + unset($this->callbacks[(int)$frame->channel][$class][$i]); + } + } } } - } - } - $this->socket = null; - }); - }); + $this->socket = null; + } + ); + } + ); } - /** - * @param int $interval - * - * @return void - */ public function heartbeat(int $interval): void { - $milliseconds = $interval * 1000; + $this->heartbeatWatcherId = Loop::repeat( + $interval, + function (string $watcherId) use ($interval) { + if ($this->socket === null) { + Loop::cancel($watcherId); - $this->heartbeat = Loop::repeat($milliseconds, function($watcher) use ($milliseconds) { - if (null === $this->socket) { - Loop::cancel($watcher); + return; + } - return; - } + $currentTime = Loop::now(); + $lastWrite = $this->lastWrite ?: $currentTime; - $currentTime = Loop::now(); - $lastWrite = $this->lastWrite ?: $currentTime; + $nextHeartbeat = $lastWrite + $interval; - /** @var int $nextHeartbeat */ - $nextHeartbeat = $lastWrite + $milliseconds; + if ($currentTime >= $nextHeartbeat) { + yield $this->write((new Buffer) + ->appendUint8(8) + ->appendUint16(0) + ->appendUint32(0) + ->appendUint8(206) + ); + } - if ($currentTime >= $nextHeartbeat) { - yield $this->write((new Buffer) - ->appendUint8(8) - ->appendUint16(0) - ->appendUint32(0) - ->appendUint8(206) - ); + unset($currentTime, $lastWrite, $nextHeartbeat); } - - unset($currentTime, $lastWrite, $nextHeartbeat); - }); + ); } - /** - * @return void - */ public function close(): void { $this->callbacks = []; - if ($this->heartbeat !== null) { - Loop::cancel($this->heartbeat); + if ($this->heartbeatWatcherId !== null) { + Loop::cancel($this->heartbeatWatcherId); - $this->heartbeat = null; + $this->heartbeatWatcherId = null; } - $this->socket->close(); + if ($this->socket !== null) { + $this->socket->close(); + } } } diff --git a/src/Constants.php b/src/Constants.php index c6fd638..2ffae93 100644 --- a/src/Constants.php +++ b/src/Constants.php @@ -14,156 +14,132 @@ final class Constants { - const CONNECTION_CHANNEL = 0; + public const CONNECTION_CHANNEL = 0; - const - FRAME_METHOD = 1, - FRAME_HEADER = 2, - FRAME_BODY = 3, - FRAME_HEARTBEAT = 8, - FRAME_MIN_SIZE = 4096, - FRAME_END = 0xCE - ; + public const FRAME_METHOD = 1; + public const FRAME_HEADER = 2; + public const FRAME_BODY = 3; + public const FRAME_HEARTBEAT = 8; + public const FRAME_MIN_SIZE = 4096; + public const FRAME_END = 0xCE; - const - STATUS_REPLY_SUCCESS = 200, - STATUS_CONTENT_TOO_LARGE = 311, - STATUS_NO_ROUTE = 312, - STATUS_NO_CONSUMERS = 313, - STATUS_CONNECTION_FORCED = 320, - STATUS_INVALID_PATH = 402, - STATUS_ACCESS_REFUSED = 403, - STATUS_NOT_FOUND = 404, - STATUS_RESOURCE_LOCKED = 405, - STATUS_PRECONDITION_FAILED = 406, - STATUS_FRAME_ERROR = 501, - STATUS_SYNTAX_ERROR = 502, - STATUS_COMMAND_INVALID = 503, - STATUS_CHANNEL_ERROR = 504, - STATUS_UNEXPECTED_FRAME = 505, - STATUS_RESOURCE_ERROR = 506, - STATUS_NOT_ALLOWED = 530, - STATUS_NOT_IMPLEMENTED = 540, - STATUS_INTERNAL_ERROR = 541 - ; + public const STATUS_REPLY_SUCCESS = 200; + public const STATUS_CONTENT_TOO_LARGE = 311; + public const STATUS_NO_ROUTE = 312; + public const STATUS_NO_CONSUMERS = 313; + public const STATUS_CONNECTION_FORCED = 320; + public const STATUS_INVALID_PATH = 402; + public const STATUS_ACCESS_REFUSED = 403; + public const STATUS_NOT_FOUND = 404; + public const STATUS_RESOURCE_LOCKED = 405; + public const STATUS_PRECONDITION_FAILED = 406; + public const STATUS_FRAME_ERROR = 501; + public const STATUS_SYNTAX_ERROR = 502; + public const STATUS_COMMAND_INVALID = 503; + public const STATUS_CHANNEL_ERROR = 504; + public const STATUS_UNEXPECTED_FRAME = 505; + public const STATUS_RESOURCE_ERROR = 506; + public const STATUS_NOT_ALLOWED = 530; + public const STATUS_NOT_IMPLEMENTED = 540; + public const STATUS_INTERNAL_ERROR = 541; - const - CLASS_CONNECTION = 10, - CLASS_CHANNEL = 20, - CLASS_ACCESS = 30, - CLASS_EXCHANGE = 40, - CLASS_QUEUE = 50, - CLASS_BASIC = 60, - CLASS_TX = 90, - CLASS_CONFIRM = 85 // RabbitMQ extension - ; + public const CLASS_CONNECTION = 10; + public const CLASS_CHANNEL = 20; + public const CLASS_ACCESS = 30; + public const CLASS_EXCHANGE = 40; + public const CLASS_QUEUE = 50; + public const CLASS_BASIC = 60; + public const CLASS_TX = 90; + public const CLASS_CONFIRM = 85; - const - METHOD_CONNECTION_START = 10, - METHOD_CONNECTION_START_OK = 11, - METHOD_CONNECTION_SECURE = 20, - METHOD_CONNECTION_SECURE_OK = 21, - METHOD_CONNECTION_TUNE = 30, - METHOD_CONNECTION_TUNE_OK = 31, - METHOD_CONNECTION_OPEN = 40, - METHOD_CONNECTION_OPEN_OK = 41, - METHOD_CONNECTION_CLOSE = 50, - METHOD_CONNECTION_CLOSE_OK = 51, - METHOD_CONNECTION_BLOCKED = 60, // RabbitMQ extension - METHOD_CONNECTION_UNBLOCKED = 61 // RabbitMQ extension - ; + public const METHOD_CONNECTION_START = 10; + public const METHOD_CONNECTION_START_OK = 11; + public const METHOD_CONNECTION_SECURE = 20; + public const METHOD_CONNECTION_SECURE_OK = 21; + public const METHOD_CONNECTION_TUNE = 30; + public const METHOD_CONNECTION_TUNE_OK = 31; + public const METHOD_CONNECTION_OPEN = 40; + public const METHOD_CONNECTION_OPEN_OK = 41; + public const METHOD_CONNECTION_CLOSE = 50; + public const METHOD_CONNECTION_CLOSE_OK = 51; + public const METHOD_CONNECTION_BLOCKED = 60; + public const METHOD_CONNECTION_UNBLOCKED = 61; - const - METHOD_CHANNEL_OPEN = 10, - METHOD_CHANNEL_OPEN_OK = 11, - METHOD_CHANNEL_FLOW = 20, - METHOD_CHANNEL_FLOW_OK = 21, - METHOD_CHANNEL_CLOSE = 40, - METHOD_CHANNEL_CLOSE_OK = 41 - ; + public const METHOD_CHANNEL_OPEN = 10; + public const METHOD_CHANNEL_OPEN_OK = 11; + public const METHOD_CHANNEL_FLOW = 20; + public const METHOD_CHANNEL_FLOW_OK = 21; + public const METHOD_CHANNEL_CLOSE = 40; + public const METHOD_CHANNEL_CLOSE_OK = 41; - const - METHOD_ACCESS_REQUEST = 10, - METHOD_ACCESS_REQUEST_OK = 11 - ; + public const METHOD_ACCESS_REQUEST = 10; + public const METHOD_ACCESS_REQUEST_OK = 11; - const - METHOD_EXCHANGE_DECLARE = 10, - METHOD_EXCHANGE_DECLARE_OK = 11, - METHOD_EXCHANGE_DELETE = 20, - METHOD_EXCHANGE_DELETE_OK = 21, - METHOD_EXCHANGE_BIND = 30, // RabbitMQ extension - METHOD_EXCHANGE_BIND_OK = 31, // RabbitMQ extension - METHOD_EXCHANGE_UNBIND = 40, // RabbitMQ extension - METHOD_EXCHANGE_UNBIND_OK = 51 // RabbitMQ extension - ; + public const METHOD_EXCHANGE_DECLARE = 10; + public const METHOD_EXCHANGE_DECLARE_OK = 11; + public const METHOD_EXCHANGE_DELETE = 20; + public const METHOD_EXCHANGE_DELETE_OK = 21; + public const METHOD_EXCHANGE_BIND = 30; + public const METHOD_EXCHANGE_BIND_OK = 31; + public const METHOD_EXCHANGE_UNBIND = 40; + public const METHOD_EXCHANGE_UNBIND_OK = 51; - const - METHOD_QUEUE_DECLARE = 10, - METHOD_QUEUE_DECLARE_OK = 11, - METHOD_QUEUE_BIND = 20, - METHOD_QUEUE_BIND_OK = 21, - METHOD_QUEUE_PURGE = 30, - METHOD_QUEUE_PURGE_OK = 31, - METHOD_QUEUE_DELETE = 40, - METHOD_QUEUE_DELETE_OK = 41, - METHOD_QUEUE_UNBIND = 50, - METHOD_QUEUE_UNBIND_OK = 51 - ; + public const METHOD_QUEUE_DECLARE = 10; + public const METHOD_QUEUE_DECLARE_OK = 11; + public const METHOD_QUEUE_BIND = 20; + public const METHOD_QUEUE_BIND_OK = 21; + public const METHOD_QUEUE_PURGE = 30; + public const METHOD_QUEUE_PURGE_OK = 31; + public const METHOD_QUEUE_DELETE = 40; + public const METHOD_QUEUE_DELETE_OK = 41; + public const METHOD_QUEUE_UNBIND = 50; + public const METHOD_QUEUE_UNBIND_OK = 51; - const - METHOD_BASIC_QOS = 10, - METHOD_BASIC_QOS_OK = 11, - METHOD_BASIC_CONSUME = 20, - METHOD_BASIC_CONSUME_OK = 21, - METHOD_BASIC_CANCEL = 30, - METHOD_BASIC_CANCEL_OK = 31, - METHOD_BASIC_PUBLISH = 40, - METHOD_BASIC_RETURN = 50, - METHOD_BASIC_DELIVER = 60, - METHOD_BASIC_GET = 70, - METHOD_BASIC_GET_OK = 71, - METHOD_BASIC_GET_EMPTY = 72, - METHOD_BASIC_ACK = 80, - METHOD_BASIC_REJECT = 90, - METHOD_BASIC_RECOVER_ASYNC = 100, - METHOD_BASIC_RECOVER = 110, - METHOD_BASIC_RECOVER_OK = 111, - METHOD_BASIC_NACK = 120 // RabbitMQ extension - ; + public const METHOD_BASIC_QOS = 10; + public const METHOD_BASIC_QOS_OK = 11; + public const METHOD_BASIC_CONSUME = 20; + public const METHOD_BASIC_CONSUME_OK = 21; + public const METHOD_BASIC_CANCEL = 30; + public const METHOD_BASIC_CANCEL_OK = 31; + public const METHOD_BASIC_PUBLISH = 40; + public const METHOD_BASIC_RETURN = 50; + public const METHOD_BASIC_DELIVER = 60; + public const METHOD_BASIC_GET = 70; + public const METHOD_BASIC_GET_OK = 71; + public const METHOD_BASIC_GET_EMPTY = 72; + public const METHOD_BASIC_ACK = 80; + public const METHOD_BASIC_REJECT = 90; + public const METHOD_BASIC_RECOVER_ASYNC = 100; + public const METHOD_BASIC_RECOVER = 110; + public const METHOD_BASIC_RECOVER_OK = 111; + public const METHOD_BASIC_NACK = 120; - const - METHOD_TX_SELECT = 10, - METHOD_TX_SELECT_OK = 11, - METHOD_TX_COMMIT = 20, - METHOD_TX_COMMIT_OK = 21, - METHOD_TX_ROLLBACK = 30, - METHOD_TX_ROLLBACK_OK = 31 - ; + public const METHOD_TX_SELECT = 10; + public const METHOD_TX_SELECT_OK = 11; + public const METHOD_TX_COMMIT = 20; + public const METHOD_TX_COMMIT_OK = 21; + public const METHOD_TX_ROLLBACK = 30; + public const METHOD_TX_ROLLBACK_OK = 31; - const - METHOD_CONFIRM_SELECT = 10, // RabbitMQ extension - METHOD_CONFIRM_SELECT_OK = 11 // RabbitMQ extension - ; + public const METHOD_CONFIRM_SELECT = 10; + public const METHOD_CONFIRM_SELECT_OK = 11; - const - FIELD_BOOLEAN = 0x74, // 't' - FIELD_SHORT_SHORT_INT = 0x62, // 'b' - FIELD_SHORT_SHORT_UINT = 0x42, // 'B' - FIELD_SHORT_INT = 0x55, // 'U' - FIELD_SHORT_UINT = 0x75, // 'u' - FIELD_LONG_INT = 0x49, // 'I' - FIELD_LONG_UINT = 0x69, // 'i' - FIELD_LONG_LONG_INT = 0x4C, // 'L' - FIELD_LONG_LONG_UINT = 0x6C, // 'l' - FIELD_FLOAT = 0x66, // 'f' - FIELD_DOUBLE = 0x64, // 'd' - FIELD_DECIMAL = 0x44, // 'D' - FIELD_SHORT_STRING = 0x73, // 's' - FIELD_LONG_STRING = 0x53, // 'S' - FIELD_ARRAY = 0x41, // 'A' - FIELD_TIMESTAMP = 0x54, // 'T' - FIELD_TABLE = 0x46, // 'F' - FIELD_NULL = 0x56 // 'V' - ; + public const FIELD_BOOLEAN = 0x74; // 't' + public const FIELD_SHORT_SHORT_INT = 0x62; // 'b' + public const FIELD_SHORT_SHORT_UINT = 0x42; // 'B' + public const FIELD_SHORT_INT = 0x55; // 'U' + public const FIELD_SHORT_UINT = 0x75; // 'u' + public const FIELD_LONG_INT = 0x49; // 'I' + public const FIELD_LONG_UINT = 0x69; // 'i' + public const FIELD_LONG_LONG_INT = 0x4C; // 'L' + public const FIELD_LONG_LONG_UINT = 0x6C; // 'l' + public const FIELD_FLOAT = 0x66; // 'f' + public const FIELD_DOUBLE = 0x64; // 'd' + public const FIELD_DECIMAL = 0x44; // 'D' + public const FIELD_SHORT_STRING = 0x73; // 's' + public const FIELD_LONG_STRING = 0x53; // 'S' + public const FIELD_ARRAY = 0x41; // 'A' + public const FIELD_TIMESTAMP = 0x54; // 'T' + public const FIELD_TABLE = 0x46; // 'F' + public const FIELD_NULL = 0x56; // 'V' } diff --git a/src/Consumer.php b/src/Consumer.php index bea0468..f4defdd 100644 --- a/src/Consumer.php +++ b/src/Consumer.php @@ -28,61 +28,44 @@ final class Consumer /** * @var callable[] + * @psalm-var array */ private $listeners = []; - /** - * @param Channel $channel - * @param MessageReceiver $receiver - */ public function __construct(Channel $channel, MessageReceiver $receiver) { - $this->channel = $channel; + $this->channel = $channel; $this->receiver = $receiver; } - /** - * @return void - */ public function start(): void { - $this->receiver->onMessage(function (Message $message) { - if (!$tag = $message->consumerTag()) { - return; - } + $this->receiver->onMessage( + function (Message $message) { + if (!$tag = $message->consumerTag) { + return; + } - if (!isset($this->listeners[$tag])) { - return; - } + if (!isset($this->listeners[$tag])) { + return; + } - asyncCall($this->listeners[$tag], $message, $this->channel); - }); + /** @psalm-suppress MixedArgumentTypeCoercion */ + asyncCall($this->listeners[$tag], $message, $this->channel); + } + ); } - /** - * @return void - */ public function stop(): void { $this->listeners = []; } - /** - * @param string $tag - * @param callable $listener - * - * @return void - */ public function subscribe(string $tag, callable $listener): void { $this->listeners[$tag] = $listener; } - /** - * @param string $tag - * - * @return void - */ public function cancel(string $tag): void { unset($this->listeners[$tag]); diff --git a/src/Events.php b/src/Events.php index d4f20e7..b221468 100644 --- a/src/Events.php +++ b/src/Events.php @@ -26,21 +26,12 @@ final class Events */ private $receiver; - /** - * @param Channel $channel - * @param MessageReceiver $receiver - */ public function __construct(Channel $channel, MessageReceiver $receiver) { - $this->channel = $channel; + $this->channel = $channel; $this->receiver = $receiver; } - /** - * @param callable $listener - * - * @return self - */ public function onAck(callable $listener): self { $this->onFrame(Protocol\BasicAckFrame::class, $listener); @@ -48,11 +39,6 @@ public function onAck(callable $listener): self return $this; } - /** - * @param callable $listener - * - * @return self - */ public function onNack(callable $listener): self { $this->onFrame(Protocol\BasicNackFrame::class, $listener); @@ -60,34 +46,33 @@ public function onNack(callable $listener): self return $this; } - /** - * @param callable $listener - * - * @return self - */ public function onReturn(callable $listener): self { - $this->receiver->onMessage(function (Message $message) use ($listener) { - if (!$message->returned()) { - return; - } + $this->receiver->onMessage( + function (Message $message) use ($listener) { + if (!$message->returned) { + return; + } - asyncCall($listener, $message, $this->channel); - }); + /** @psalm-suppress MixedArgumentTypeCoercion */ + asyncCall($listener, $message, $this->channel); + } + ); return $this; } /** - * @param string $frame - * @param callable $callback - * - * @return void + * @psalm-param class-string $frame */ private function onFrame(string $frame, callable $callback): void { - $this->receiver->onFrame($frame, function (Protocol\AcknowledgmentFrame $frame) use ($callback) { - asyncCall($callback, $frame->deliveryTag, $frame->multiple, $this->channel); - }); + $this->receiver->onFrame( + $frame, + function (Protocol\AcknowledgmentFrame $frame) use ($callback) { + /** @psalm-suppress MixedArgumentTypeCoercion */ + asyncCall($callback, $frame->deliveryTag, $frame->multiple, $this->channel); + } + ); } } diff --git a/src/Exception/ChannelException.php b/src/Exception/ChannelException.php index 54ade30..74c3931 100644 --- a/src/Exception/ChannelException.php +++ b/src/Exception/ChannelException.php @@ -8,73 +8,46 @@ * file that was distributed with this source code. */ -declare(strict_types=1); +declare(strict_types = 1); namespace PHPinnacle\Ridge\Exception; final class ChannelException extends RidgeException { - /** - * @param int $id - * - * @return self - */ public static function notReady(int $id): self { - return new self("Trying to open not ready channel #{$id}."); + return new self(\sprintf('Trying to open not ready channel #%d.', $id)); } - - /** - * @param int $id - * - * @return self - */ + public static function alreadyClosed(int $id): self { - return new self("Trying to close already closed channel #{$id}."); + return new self(\sprintf('Trying to close already closed channel #%d.', $id)); } - /** - * @param string $mode - * - * @return self - */ public static function notRegularFor(string $mode): self { - return new self("Channel not in regular mode, cannot change to {$mode} mode."); + return new self(\sprintf('Channel not in regular mode, cannot change to %s mode.', $mode)); } - - /** - * @return self - */ + public static function notTransactional(): self { - return new self("Channel not in transactional mode."); + return new self('Channel not in transactional mode.'); } - /** - * @return self - */ public static function getInProgress(): self { - return new self("Another 'basic.get' already in progress. You should use 'basic.consume' instead of multiple 'basic.get'."); + return new self( + 'Another `basic.get` already in progress. You should use `basic.consume` instead of multiple `basic.get`.' + ); } - /** - * @return self - */ public static function frameOrder(): self { - return new self("Consume frames order malformed."); + return new self('Consume frames order malformed.'); } - /** - * @param int $remaining - * - * @return self - */ public static function bodyOverflow(int $remaining): self { - return new self("Body overflow, received {$remaining} more bytes."); + return new self(\sprintf('Body overflow, received %d more bytes.', $remaining)); } } diff --git a/src/Exception/ClassInvalid.php b/src/Exception/ClassInvalid.php index 3556ce8..ada21b3 100644 --- a/src/Exception/ClassInvalid.php +++ b/src/Exception/ClassInvalid.php @@ -14,11 +14,8 @@ final class ClassInvalid extends ProtocolException { - /** - * @param int $classId - */ public function __construct(int $classId) { - parent::__construct("Unhandled method frame class '{$classId}'."); + parent::__construct(\sprintf('Unhandled method frame class `%d`.', $classId)); } } diff --git a/src/Exception/ClientException.php b/src/Exception/ClientException.php index 916d3fe..d7b2b40 100644 --- a/src/Exception/ClientException.php +++ b/src/Exception/ClientException.php @@ -16,77 +16,43 @@ final class ClientException extends RidgeException { - /** - * @param \Throwable $error - * - * @return self - */ public static function unexpectedResponse(\Throwable $error): self { - return new self("Unexpected response.", $error->getCode(), $error); + return new self('Unexpected response.', (int)$error->getCode(), $error); } - /** - * @return self - */ public static function notConnected(): self { - return new self("Client is not connected to server."); + return new self('Client is not connected to server.'); } - /** - * @return self - */ public static function alreadyConnected(): self { - return new self("Client is already connected/connecting."); + return new self('Client is already connected/connecting.'); } - - /** - * @param string $available - * - * @return self - */ + public static function notSupported(string $available): self { - return new self("Server does not support AMQPLAIN mechanism (supported: {$available})."); + return new self(\sprintf('Server does not support AMQPLAIN mechanism (supported: %s).', $available)); } - - /** - * @return self - */ + public static function noChannelsAvailable(): self { - return new self("No available channels."); + return new self('No available channels.'); } - /** - * @param Protocol\ConnectionCloseFrame $frame - * - * @return self - */ public static function connectionClosed(Protocol\ConnectionCloseFrame $frame): self { - return new self("Connection closed by server: {$frame->replyText}.", $frame->replyCode); + return new self(\sprintf('Connection closed by server: %s.', $frame->replyText), $frame->replyCode); } - /** - * @param Protocol\AbstractFrame $frame - * - * @return self - */ public static function unknownFrameClass(Protocol\AbstractFrame $frame): self { - return new self("Unhandled frame '" . \get_class($frame) . "'."); + return new self(\sprintf('Unhandled frame `%s`.', \get_class($frame))); } - /** - * @param Protocol\AbstractFrame $frame - * - * @return self - */ public static function unknownMethodFrame(Protocol\AbstractFrame $frame): self { - return new self("Unhandled method frame '" . \get_class($frame) . "'."); + return new self(\sprintf('Unhandled method frame `%s`.', \get_class($frame))); } } diff --git a/src/Exception/ConfigurationException.php b/src/Exception/ConfigurationException.php new file mode 100644 index 0000000..d25661c --- /dev/null +++ b/src/Exception/ConfigurationException.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace PHPinnacle\Ridge\Exception; + +/** + * + */ +final class ConfigurationException extends RidgeException +{ + public static function emptyDSN(): self + { + return new self('Connection DSN can\'t be empty'); + } + + public static function incorrectDSN(string $dsn): self + { + return new self(\sprintf('Can\'t parse specified connection DSN (%s)', $dsn)); + } +} diff --git a/src/Exception/ConnectionException.php b/src/Exception/ConnectionException.php new file mode 100644 index 0000000..b952207 --- /dev/null +++ b/src/Exception/ConnectionException.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace PHPinnacle\Ridge\Exception; + +/** + * + */ +final class ConnectionException extends RidgeException +{ + public static function writeFailed(\Throwable $previous): self + { + return new self( + \sprintf('Error writing to socket: %s', $previous->getMessage()), + (int)$previous->getCode(), + $previous + ); + } + + public static function socketClosed(): self + { + return new self('Attempting to write to a closed socket'); + } +} diff --git a/src/Exception/MethodInvalid.php b/src/Exception/MethodInvalid.php index 0231fed..0ed160f 100644 --- a/src/Exception/MethodInvalid.php +++ b/src/Exception/MethodInvalid.php @@ -14,12 +14,8 @@ final class MethodInvalid extends ProtocolException { - /** - * @param int $classId - * @param int $methodId - */ public function __construct(int $classId, int $methodId) { - parent::__construct("Unhandled method frame method '{$methodId}' in class '{$classId}'."); + parent::__construct(\sprintf('Unhandled method frame method `%d` in class `%d`.', $methodId, $classId)); } } diff --git a/src/Exception/ProtocolException.php b/src/Exception/ProtocolException.php index 44ffe51..74c0978 100644 --- a/src/Exception/ProtocolException.php +++ b/src/Exception/ProtocolException.php @@ -17,67 +17,48 @@ class ProtocolException extends RidgeException { - /** - * @param int $frameEnd - * - * @return self - */ public static function invalidFrameEnd(int $frameEnd): self { - $message = \sprintf("Frame end byte invalid - expected 0x%02x, got 0x%02x.", Constants::FRAME_END, $frameEnd); - - return new self($message); + return new self( + \sprintf( + 'Frame end byte invalid - expected 0x%02x, got 0x%02x.', + Constants::FRAME_END, + $frameEnd + ) + ); } - /** - * @param int $type - * - * @return self - */ public static function unknownFrameType(int $type): self { - return new self("Unhandled frame type '{$type}'."); + return new self(\sprintf('Unhandled frame type `%d`.', $type)); } - /** - * @param AbstractFrame $frame - * - * @return self - */ public static function unknownFrameClass(AbstractFrame $frame): self { - return new self("Unhandled frame '" . get_class($frame) . "'."); + return new self(\sprintf('Unhandled frame `%s`', \get_class($frame))); } - /** - * @return self - */ public static function notEmptyHeartbeat(): self { - return new self("Heartbeat frame must be empty."); + return new self('Heartbeat frame must be empty.'); } - /** - * @param int $fieldType - * - * @return self - */ public static function unknownFieldType(int $fieldType): self { - $cType = \ctype_print(\chr($fieldType)) ? " ('" . \chr($fieldType) . "')" : ""; + $cType = \ctype_print(\chr($fieldType)) ? ' (`' . \chr($fieldType) . '`)' : ''; - return new self(\sprintf("Unhandled field type 0x%02x%s.", $fieldType, $cType)); + return new self(\sprintf('Unhandled field type 0x%02x%s.', $fieldType, $cType)); } - /** - * @param int $fieldType - * - * @return self - */ - public static function unknownValueType($value): self + public static function unknownValueType(mixed $value): self { - $class = (\is_object($value) ? " (class " . \get_class($value) . ")" : ""); + $class = (\is_object($value) ? ' (class `' . \get_class($value) . '`)' : ''); + + return new self(\sprintf('Unhandled value type `%s`%s.', \gettype($value), $class)); + } - return new self(\sprintf("Unhandled value type '%s'%s.", \gettype($value), $class)); + public static function unsupportedDeliveryTag(): self + { + return new self('Delivery tag can\'t be null'); } } diff --git a/src/Message.php b/src/Message.php index f3606ac..3d1a3ea 100644 --- a/src/Message.php +++ b/src/Message.php @@ -15,148 +15,82 @@ final class Message { /** + * @psalm-readonly + * * @var string */ - private $content; + public $content; /** + * @psalm-readonly + * * @var string */ - private $exchange; + public $exchange; /** + * @psalm-readonly + * * @var string */ - private $routingKey; + public $routingKey; /** - * @var string + * @psalm-readonly + * + * @var string|null */ - private $consumerTag; + public $consumerTag; /** - * @var int + * @psalm-readonly + * + * @var int|null */ - private $deliveryTag; + public $deliveryTag; /** + * @psalm-readonly + * * @var bool */ - private $redelivered; + public $redelivered; /** + * @psalm-readonly + * * @var bool */ - private $returned; + public $returned; /** + * @psalm-readonly + * * @var array */ - private $headers; + public $headers; - /** - * @param string $content - * @param string $exchange - * @param string $routingKey - * @param string $consumerTag - * @param int $deliveryTag - * @param bool $redelivered - * @param bool $returned - * @param array $headers - */ public function __construct( string $content, string $exchange, string $routingKey, - string $consumerTag = null, - int $deliveryTag = null, + ?string $consumerTag = null, + ?int $deliveryTag = null, bool $redelivered = false, bool $returned = false, array $headers = [] ) { - $this->content = $content; - $this->exchange = $exchange; - $this->routingKey = $routingKey; + $this->content = $content; + $this->exchange = $exchange; + $this->routingKey = $routingKey; $this->consumerTag = $consumerTag; $this->deliveryTag = $deliveryTag; $this->redelivered = $redelivered; - $this->returned = $returned; - $this->headers = $headers; - } - - /** - * @return string - */ - public function content(): string - { - return $this->content; - } - - /** - * @return string - */ - public function exchange(): string - { - return $this->exchange; + $this->returned = $returned; + $this->headers = $headers; } - /** - * @return string - */ - public function routingKey(): string - { - return $this->routingKey; - } - - /** - * @return string - */ - public function consumerTag(): ?string - { - return $this->consumerTag; - } - - /** - * @return int - */ - public function deliveryTag(): ?int - { - return $this->deliveryTag; - } - - /** - * @return bool - */ - public function redelivered(): bool - { - return $this->redelivered; - } - - /** - * @return bool - */ - public function returned(): bool - { - return $this->returned; - } - - /** - * @return array - */ - public function headers(): array - { - return $this->headers; - } - - /** - * Returns header or default value. - * - * @param string $name - * @param mixed $default - * - * @return mixed - */ - public function header(string $name, $default = null) + public function header(string $name, mixed $default = null): mixed { return $this->headers[$name] ?? $default; } diff --git a/src/MessageReceiver.php b/src/MessageReceiver.php index 991790e..e778f47 100644 --- a/src/MessageReceiver.php +++ b/src/MessageReceiver.php @@ -16,11 +16,10 @@ final class MessageReceiver { - const + public const STATE_WAIT = 0, STATE_HEAD = 1, - STATE_BODY = 2 - ; + STATE_BODY = 2; /** * @var Channel @@ -53,34 +52,27 @@ final class MessageReceiver private $callbacks = []; /** - * @var Protocol\BasicDeliverFrame + * @var Protocol\BasicDeliverFrame|null */ private $deliver; /** - * @var Protocol\BasicReturnFrame + * @var Protocol\BasicReturnFrame|null */ private $return; /** - * @var Protocol\ContentHeaderFrame + * @var Protocol\ContentHeaderFrame|null */ private $header; - /** - * @param Channel $channel - * @param Connection $connection - */ public function __construct(Channel $channel, Connection $connection) { - $this->channel = $channel; + $this->channel = $channel; $this->connection = $connection; - $this->buffer = new Buffer; + $this->buffer = new Buffer; } - /** - * @return void - */ public function start(): void { $this->onFrame(Protocol\BasicReturnFrame::class, [$this, 'receiveReturn']); @@ -89,40 +81,24 @@ public function start(): void $this->onFrame(Protocol\ContentBodyFrame::class, [$this, 'receiveBody']); } - /** - * @return void - */ public function stop(): void { $this->callbacks = []; } - /** - * @param callable $callback - * - * @return void - */ public function onMessage(callable $callback): void { $this->callbacks[] = $callback; } /** - * @param string $frame - * @param callable $callback - * - * @return void + * @psalm-param class-string $frame */ public function onFrame(string $frame, callable $callback): void { $this->connection->subscribe($this->channel->id(), $frame, $callback); } - /** - * @param Protocol\BasicReturnFrame $frame - * - * @return void - */ public function receiveReturn(Protocol\BasicReturnFrame $frame): void { if ($this->state !== self::STATE_WAIT) { @@ -130,14 +106,9 @@ public function receiveReturn(Protocol\BasicReturnFrame $frame): void } $this->return = $frame; - $this->state = self::STATE_HEAD; + $this->state = self::STATE_HEAD; } - /** - * @param Protocol\BasicDeliverFrame $frame - * - * @return void - */ public function receiveDeliver(Protocol\BasicDeliverFrame $frame): void { if ($this->state !== self::STATE_WAIT) { @@ -145,41 +116,31 @@ public function receiveDeliver(Protocol\BasicDeliverFrame $frame): void } $this->deliver = $frame; - $this->state = self::STATE_HEAD; + $this->state = self::STATE_HEAD; } - /** - * @param Protocol\ContentHeaderFrame $frame - * - * @return void - */ public function receiveHeader(Protocol\ContentHeaderFrame $frame): void { if ($this->state !== self::STATE_HEAD) { return; } - $this->state = self::STATE_BODY; - $this->header = $frame; + $this->state = self::STATE_BODY; + $this->header = $frame; $this->remaining = $frame->bodySize; $this->runCallbacks(); } - /** - * @param Protocol\ContentBodyFrame $frame - * - * @return void - */ public function receiveBody(Protocol\ContentBodyFrame $frame): void { if ($this->state !== self::STATE_BODY) { return; } - $this->buffer->append($frame->payload); + $this->buffer->append((string)$frame->payload); - $this->remaining -= $frame->size; + $this->remaining -= (int)$frame->size; if ($this->remaining < 0) { throw Exception\ChannelException::bodyOverflow($this->remaining); @@ -189,7 +150,7 @@ public function receiveBody(Protocol\ContentBodyFrame $frame): void } /** - * @return void + * @throws \PHPinnacle\Ridge\Exception\ChannelException */ private function runCallbacks(): void { @@ -206,28 +167,31 @@ private function runCallbacks(): void null, false, true, - $this->header->toArray() - ); - } elseif ($this->deliver) { - $message = new Message( - $this->buffer->flush(), - $this->deliver->exchange, - $this->deliver->routingKey, - $this->deliver->consumerTag, - $this->deliver->deliveryTag, - $this->deliver->redelivered, - false, - $this->header->toArray() + $this->header !== null ? $this->header->toArray() : [] ); } else { - throw Exception\ChannelException::frameOrder(); + if ($this->deliver) { + $message = new Message( + $this->buffer->flush(), + $this->deliver->exchange, + $this->deliver->routingKey, + $this->deliver->consumerTag, + $this->deliver->deliveryTag, + $this->deliver->redelivered, + false, + $this->header !== null ? $this->header->toArray() : [] + ); + } else { + throw Exception\ChannelException::frameOrder(); + } } - $this->return = null; + $this->return = null; $this->deliver = null; - $this->header = null; + $this->header = null; foreach ($this->callbacks as $callback) { + /** @psalm-suppress MixedArgumentTypeCoercion */ asyncCall($callback, $message); } diff --git a/src/Parser.php b/src/Parser.php index 822e20c..7c85d6b 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -22,11 +22,6 @@ public function __construct() $this->buffer = new Buffer; } - /** - * @param string $chunk - * - * @return void - */ public function append(string $chunk): void { $this->buffer->append($chunk); @@ -37,7 +32,8 @@ public function append(string $chunk): void * * Returns NULL if there are not enough data to construct whole frame. * - * @return Protocol\AbstractFrame + * @throws \PHPinnacle\Buffer\BufferOverflow + * @throws \PHPinnacle\Ridge\Exception\ProtocolException */ public function parse(): ?Protocol\AbstractFrame { @@ -45,16 +41,16 @@ public function parse(): ?Protocol\AbstractFrame return null; } - $size = $this->buffer->readUint32(3); + $size = $this->buffer->readUint32(3); $length = $size + 8; if ($this->buffer->size() < $length) { return null; } - $type = $this->buffer->readUint8(0); - $channel = $this->buffer->readUint16(1); - $payload = $this->buffer->read($size, 7); + $type = $this->buffer->readUint8(); + $channel = $this->buffer->readUint16(1); + $payload = $this->buffer->read($size, 7); $frameEnd = $this->buffer->readUint8($length - 1); $this->buffer->discard($length); @@ -86,8 +82,8 @@ public function parse(): ?Protocol\AbstractFrame } /** @var Protocol\AbstractFrame $frame */ - $frame->type = $type; - $frame->size = $size; + $frame->type = $type; + $frame->size = $size; $frame->channel = $channel; return $frame; @@ -96,253 +92,171 @@ public function parse(): ?Protocol\AbstractFrame /** * Consumes AMQP method frame. * - * @param Buffer $buffer - * - * @return Protocol\MethodFrame + * @throws \PHPinnacle\Buffer\BufferOverflow + * @throws \PHPinnacle\Ridge\Exception\ClassInvalid */ private function consumeMethodFrame(Buffer $buffer): Protocol\MethodFrame { - $classId = $buffer->consumeUint16(); + $classId = $buffer->consumeUint16(); $methodId = $buffer->consumeUint16(); - switch ($classId) { - case Constants::CLASS_BASIC: - return $this->consumeBasicFrame($methodId, $buffer); - case Constants::CLASS_CONNECTION: - return $this->consumeConnectionFrame($methodId, $buffer); - case Constants::CLASS_CHANNEL: - return $this->consumeChannelFrame($methodId, $buffer); - case Constants::CLASS_EXCHANGE: - return $this->consumeExchangeFrame($methodId, $buffer); - case Constants::CLASS_QUEUE: - return $this->consumeQueueFrame($methodId, $buffer); - case Constants::CLASS_TX: - return $this->consumeTxFrame($methodId); - case Constants::CLASS_CONFIRM: - return $this->consumeConfirmFrame($methodId, $buffer); - default: - throw new Exception\ClassInvalid($classId); - } + return match ($classId) { + Constants::CLASS_BASIC => $this->consumeBasicFrame($methodId, $buffer), + Constants::CLASS_CONNECTION => $this->consumeConnectionFrame($methodId, $buffer), + Constants::CLASS_CHANNEL => $this->consumeChannelFrame($methodId, $buffer), + Constants::CLASS_EXCHANGE => $this->consumeExchangeFrame($methodId, $buffer), + Constants::CLASS_QUEUE => $this->consumeQueueFrame($methodId, $buffer), + Constants::CLASS_TX => $this->consumeTxFrame($methodId), + Constants::CLASS_CONFIRM => $this->consumeConfirmFrame($methodId, $buffer), + default => throw new Exception\ClassInvalid($classId), + }; } - + /** - * @param int $methodId - * @param Buffer $buffer - * * @return Protocol\MethodFrame + * + * @throws \PHPinnacle\Ridge\Exception\MethodInvalid + * @throws \PHPinnacle\Buffer\BufferOverflow */ private function consumeBasicFrame(int $methodId, Buffer $buffer): Protocol\MethodFrame { - switch ($methodId) { - case Constants::METHOD_BASIC_DELIVER: - return Protocol\BasicDeliverFrame::unpack($buffer); - case Constants::METHOD_BASIC_GET: - return Protocol\BasicGetFrame::unpack($buffer); - case Constants::METHOD_BASIC_GET_OK: - return Protocol\BasicGetOkFrame::unpack($buffer); - case Constants::METHOD_BASIC_GET_EMPTY: - return Protocol\BasicGetEmptyFrame::unpack($buffer); - case Constants::METHOD_BASIC_PUBLISH: - return Protocol\BasicPublishFrame::unpack($buffer); - case Constants::METHOD_BASIC_RETURN: - return Protocol\BasicReturnFrame::unpack($buffer); - case Constants::METHOD_BASIC_ACK: - return Protocol\BasicAckFrame::unpack($buffer); - case Constants::METHOD_BASIC_NACK: - return Protocol\BasicNackFrame::unpack($buffer); - case Constants::METHOD_BASIC_REJECT: - return Protocol\BasicRejectFrame::unpack($buffer); - case Constants::METHOD_BASIC_QOS: - return Protocol\BasicQosFrame::unpack($buffer); - case Constants::METHOD_BASIC_QOS_OK: - return new Protocol\BasicQosOkFrame; - case Constants::METHOD_BASIC_CONSUME: - return Protocol\BasicConsumeFrame::unpack($buffer); - case Constants::METHOD_BASIC_CONSUME_OK: - return Protocol\BasicConsumeOkFrame::unpack($buffer); - case Constants::METHOD_BASIC_CANCEL: - return Protocol\BasicCancelFrame::unpack($buffer); - case Constants::METHOD_BASIC_CANCEL_OK: - return Protocol\BasicCancelOkFrame::unpack($buffer); - case Constants::METHOD_BASIC_RECOVER: - return Protocol\BasicRecoverFrame::unpack($buffer); - case Constants::METHOD_BASIC_RECOVER_OK: - return new Protocol\BasicRecoverOkFrame; - case Constants::METHOD_BASIC_RECOVER_ASYNC: - return Protocol\BasicRecoverAsyncFrame::unpack($buffer); - default: - throw new Exception\MethodInvalid(Constants::CLASS_BASIC, $methodId); - } + return match ($methodId) { + Constants::METHOD_BASIC_DELIVER => Protocol\BasicDeliverFrame::unpack($buffer), + Constants::METHOD_BASIC_GET => Protocol\BasicGetFrame::unpack($buffer), + Constants::METHOD_BASIC_GET_OK => Protocol\BasicGetOkFrame::unpack($buffer), + Constants::METHOD_BASIC_GET_EMPTY => Protocol\BasicGetEmptyFrame::unpack($buffer), + Constants::METHOD_BASIC_PUBLISH => Protocol\BasicPublishFrame::unpack($buffer), + Constants::METHOD_BASIC_RETURN => Protocol\BasicReturnFrame::unpack($buffer), + Constants::METHOD_BASIC_ACK => Protocol\BasicAckFrame::unpack($buffer), + Constants::METHOD_BASIC_NACK => Protocol\BasicNackFrame::unpack($buffer), + Constants::METHOD_BASIC_REJECT => Protocol\BasicRejectFrame::unpack($buffer), + Constants::METHOD_BASIC_QOS => Protocol\BasicQosFrame::unpack($buffer), + Constants::METHOD_BASIC_QOS_OK => new Protocol\BasicQosOkFrame, + Constants::METHOD_BASIC_CONSUME => Protocol\BasicConsumeFrame::unpack($buffer), + Constants::METHOD_BASIC_CONSUME_OK => Protocol\BasicConsumeOkFrame::unpack($buffer), + Constants::METHOD_BASIC_CANCEL => Protocol\BasicCancelFrame::unpack($buffer), + Constants::METHOD_BASIC_CANCEL_OK => Protocol\BasicCancelOkFrame::unpack($buffer), + Constants::METHOD_BASIC_RECOVER => Protocol\BasicRecoverFrame::unpack($buffer), + Constants::METHOD_BASIC_RECOVER_OK => new Protocol\BasicRecoverOkFrame, + Constants::METHOD_BASIC_RECOVER_ASYNC => Protocol\BasicRecoverAsyncFrame::unpack($buffer), + default => throw new Exception\MethodInvalid(Constants::CLASS_BASIC, $methodId), + }; } - + /** - * @param int $methodId - * @param Buffer $buffer - * * @return Protocol\MethodFrame + * + * @throws \PHPinnacle\Ridge\Exception\MethodInvalid + * @throws \PHPinnacle\Buffer\BufferOverflow */ private function consumeConnectionFrame(int $methodId, Buffer $buffer): Protocol\MethodFrame { - switch ($methodId) { - case Constants::METHOD_CONNECTION_START: - return Protocol\ConnectionStartFrame::unpack($buffer); - case Constants::METHOD_CONNECTION_START_OK: - return Protocol\ConnectionStartOkFrame::unpack($buffer); - case Constants::METHOD_CONNECTION_SECURE: - return Protocol\ConnectionSecureFrame::unpack($buffer); - case Constants::METHOD_CONNECTION_SECURE_OK: - return Protocol\ConnectionSecureOkFrame::unpack($buffer); - case Constants::METHOD_CONNECTION_TUNE: - return Protocol\ConnectionTuneFrame::unpack($buffer); - case Constants::METHOD_CONNECTION_TUNE_OK: - return Protocol\ConnectionTuneOkFrame::unpack($buffer); - case Constants::METHOD_CONNECTION_OPEN: - return Protocol\ConnectionOpenFrame::unpack($buffer); - case Constants::METHOD_CONNECTION_OPEN_OK: - return Protocol\ConnectionOpenOkFrame::unpack($buffer); - case Constants::METHOD_CONNECTION_CLOSE: - return Protocol\ConnectionCloseFrame::unpack($buffer); - case Constants::METHOD_CONNECTION_CLOSE_OK: - return new Protocol\ConnectionCloseOkFrame; - case Constants::METHOD_CONNECTION_BLOCKED: - return Protocol\ConnectionBlockedFrame::unpack($buffer); - case Constants::METHOD_CONNECTION_UNBLOCKED: - return new Protocol\ConnectionUnblockedFrame; - default: - throw new Exception\MethodInvalid(Constants::CLASS_CONNECTION, $methodId); - } + return match ($methodId) { + Constants::METHOD_CONNECTION_START => Protocol\ConnectionStartFrame::unpack($buffer), + Constants::METHOD_CONNECTION_START_OK => Protocol\ConnectionStartOkFrame::unpack($buffer), + Constants::METHOD_CONNECTION_SECURE => Protocol\ConnectionSecureFrame::unpack($buffer), + Constants::METHOD_CONNECTION_SECURE_OK => Protocol\ConnectionSecureOkFrame::unpack($buffer), + Constants::METHOD_CONNECTION_TUNE => Protocol\ConnectionTuneFrame::unpack($buffer), + Constants::METHOD_CONNECTION_TUNE_OK => Protocol\ConnectionTuneOkFrame::unpack($buffer), + Constants::METHOD_CONNECTION_OPEN => Protocol\ConnectionOpenFrame::unpack($buffer), + Constants::METHOD_CONNECTION_OPEN_OK => Protocol\ConnectionOpenOkFrame::unpack($buffer), + Constants::METHOD_CONNECTION_CLOSE => Protocol\ConnectionCloseFrame::unpack($buffer), + Constants::METHOD_CONNECTION_CLOSE_OK => new Protocol\ConnectionCloseOkFrame, + Constants::METHOD_CONNECTION_BLOCKED => Protocol\ConnectionBlockedFrame::unpack($buffer), + Constants::METHOD_CONNECTION_UNBLOCKED => new Protocol\ConnectionUnblockedFrame, + default => throw new Exception\MethodInvalid(Constants::CLASS_CONNECTION, $methodId), + }; } - + /** - * @param int $methodId - * @param Buffer $buffer - * * @return Protocol\MethodFrame + * + * @throws \PHPinnacle\Ridge\Exception\MethodInvalid + * @throws \PHPinnacle\Buffer\BufferOverflow */ private function consumeChannelFrame(int $methodId, Buffer $buffer): Protocol\MethodFrame { - switch ($methodId) { - case Constants::METHOD_CHANNEL_OPEN: - return Protocol\ChannelOpenFrame::unpack($buffer); - case Constants::METHOD_CHANNEL_OPEN_OK: - return Protocol\ChannelOpenOkFrame::unpack($buffer); - case Constants::METHOD_CHANNEL_FLOW: - return Protocol\ChannelFlowFrame::unpack($buffer); - case Constants::METHOD_CHANNEL_FLOW_OK: - return Protocol\ChannelFlowOkFrame::unpack($buffer); - case Constants::METHOD_CHANNEL_CLOSE: - return Protocol\ChannelCloseFrame::unpack($buffer); - case Constants::METHOD_CHANNEL_CLOSE_OK: - return new Protocol\ChannelCloseOkFrame; - default: - throw new Exception\MethodInvalid(Constants::CLASS_CHANNEL, $methodId); - } + return match ($methodId) { + Constants::METHOD_CHANNEL_OPEN => Protocol\ChannelOpenFrame::unpack($buffer), + Constants::METHOD_CHANNEL_OPEN_OK => Protocol\ChannelOpenOkFrame::unpack($buffer), + Constants::METHOD_CHANNEL_FLOW => Protocol\ChannelFlowFrame::unpack($buffer), + Constants::METHOD_CHANNEL_FLOW_OK => Protocol\ChannelFlowOkFrame::unpack($buffer), + Constants::METHOD_CHANNEL_CLOSE => Protocol\ChannelCloseFrame::unpack($buffer), + Constants::METHOD_CHANNEL_CLOSE_OK => new Protocol\ChannelCloseOkFrame, + default => throw new Exception\MethodInvalid(Constants::CLASS_CHANNEL, $methodId), + }; } - + /** - * @param int $methodId - * @param Buffer $buffer - * * @return Protocol\MethodFrame + * + * @throws \PHPinnacle\Ridge\Exception\MethodInvalid + * @throws \PHPinnacle\Buffer\BufferOverflow */ private function consumeExchangeFrame(int $methodId, Buffer $buffer): Protocol\MethodFrame { - switch ($methodId) { - case Constants::METHOD_EXCHANGE_DECLARE: - return Protocol\ExchangeDeclareFrame::unpack($buffer); - case Constants::METHOD_EXCHANGE_DECLARE_OK: - return new Protocol\ExchangeDeclareOkFrame; - case Constants::METHOD_EXCHANGE_DELETE: - return Protocol\ExchangeDeleteFrame::unpack($buffer); - case Constants::METHOD_EXCHANGE_DELETE_OK: - return new Protocol\ExchangeDeleteOkFrame; - case Constants::METHOD_EXCHANGE_BIND: - return Protocol\ExchangeBindFrame::unpack($buffer); - case Constants::METHOD_EXCHANGE_BIND_OK: - return new Protocol\ExchangeBindOkFrame; - case Constants::METHOD_EXCHANGE_UNBIND: - return Protocol\ExchangeUnbindFrame::unpack($buffer); - case Constants::METHOD_EXCHANGE_UNBIND_OK: - return new Protocol\ExchangeUnbindOkFrame; - default: - throw new Exception\MethodInvalid(Constants::CLASS_EXCHANGE, $methodId); - } + return match ($methodId) { + Constants::METHOD_EXCHANGE_DECLARE => Protocol\ExchangeDeclareFrame::unpack($buffer), + Constants::METHOD_EXCHANGE_DECLARE_OK => new Protocol\ExchangeDeclareOkFrame, + Constants::METHOD_EXCHANGE_DELETE => Protocol\ExchangeDeleteFrame::unpack($buffer), + Constants::METHOD_EXCHANGE_DELETE_OK => new Protocol\ExchangeDeleteOkFrame, + Constants::METHOD_EXCHANGE_BIND => Protocol\ExchangeBindFrame::unpack($buffer), + Constants::METHOD_EXCHANGE_BIND_OK => new Protocol\ExchangeBindOkFrame, + Constants::METHOD_EXCHANGE_UNBIND => Protocol\ExchangeUnbindFrame::unpack($buffer), + Constants::METHOD_EXCHANGE_UNBIND_OK => new Protocol\ExchangeUnbindOkFrame, + default => throw new Exception\MethodInvalid(Constants::CLASS_EXCHANGE, $methodId), + }; } /** - * @param int $methodId - * @param Buffer $buffer - * * @return Protocol\MethodFrame + * + * @throws \PHPinnacle\Ridge\Exception\MethodInvalid + * @throws \PHPinnacle\Buffer\BufferOverflow */ private function consumeQueueFrame(int $methodId, Buffer $buffer): Protocol\MethodFrame { - switch ($methodId) { - case Constants::METHOD_QUEUE_DECLARE: - return Protocol\QueueDeclareFrame::unpack($buffer); - case Constants::METHOD_QUEUE_DECLARE_OK: - return Protocol\QueueDeclareOkFrame::unpack($buffer); - case Constants::METHOD_QUEUE_BIND: - return Protocol\QueueBindFrame::unpack($buffer); - case Constants::METHOD_QUEUE_BIND_OK: - return new Protocol\QueueBindOkFrame; - case Constants::METHOD_QUEUE_UNBIND: - return Protocol\QueueUnbindFrame::unpack($buffer); - case Constants::METHOD_QUEUE_UNBIND_OK: - return new Protocol\QueueUnbindOkFrame; - case Constants::METHOD_QUEUE_PURGE: - return Protocol\QueuePurgeFrame::unpack($buffer); - case Constants::METHOD_QUEUE_PURGE_OK: - return Protocol\QueuePurgeOkFrame::unpack($buffer); - case Constants::METHOD_QUEUE_DELETE: - return Protocol\QueueDeleteFrame::unpack($buffer); - case Constants::METHOD_QUEUE_DELETE_OK: - return Protocol\QueueDeleteOkFrame::unpack($buffer); - default: - throw new Exception\MethodInvalid(Constants::CLASS_QUEUE, $methodId); - } + return match ($methodId) { + Constants::METHOD_QUEUE_DECLARE => Protocol\QueueDeclareFrame::unpack($buffer), + Constants::METHOD_QUEUE_DECLARE_OK => Protocol\QueueDeclareOkFrame::unpack($buffer), + Constants::METHOD_QUEUE_BIND => Protocol\QueueBindFrame::unpack($buffer), + Constants::METHOD_QUEUE_BIND_OK => new Protocol\QueueBindOkFrame, + Constants::METHOD_QUEUE_UNBIND => Protocol\QueueUnbindFrame::unpack($buffer), + Constants::METHOD_QUEUE_UNBIND_OK => new Protocol\QueueUnbindOkFrame, + Constants::METHOD_QUEUE_PURGE => Protocol\QueuePurgeFrame::unpack($buffer), + Constants::METHOD_QUEUE_PURGE_OK => Protocol\QueuePurgeOkFrame::unpack($buffer), + Constants::METHOD_QUEUE_DELETE => Protocol\QueueDeleteFrame::unpack($buffer), + Constants::METHOD_QUEUE_DELETE_OK => Protocol\QueueDeleteOkFrame::unpack($buffer), + default => throw new Exception\MethodInvalid(Constants::CLASS_QUEUE, $methodId), + }; } - + /** - * @param int $methodId - * - * @return Protocol\MethodFrame + * @throws \PHPinnacle\Ridge\Exception\MethodInvalid */ private function consumeTxFrame(int $methodId): Protocol\MethodFrame { - switch ($methodId) { - case Constants::METHOD_TX_SELECT: - return new Protocol\TxSelectFrame; - case Constants::METHOD_TX_SELECT_OK: - return new Protocol\TxSelectOkFrame; - case Constants::METHOD_TX_COMMIT: - return new Protocol\TxCommitFrame; - case Constants::METHOD_TX_COMMIT_OK: - return new Protocol\TxCommitOkFrame; - case Constants::METHOD_TX_ROLLBACK: - return new Protocol\TxRollbackFrame; - case Constants::METHOD_TX_ROLLBACK_OK: - return new Protocol\TxRollbackOkFrame; - default: - throw new Exception\MethodInvalid(Constants::CLASS_TX, $methodId); - } + return match ($methodId) { + Constants::METHOD_TX_SELECT => new Protocol\TxSelectFrame, + Constants::METHOD_TX_SELECT_OK => new Protocol\TxSelectOkFrame, + Constants::METHOD_TX_COMMIT => new Protocol\TxCommitFrame, + Constants::METHOD_TX_COMMIT_OK => new Protocol\TxCommitOkFrame, + Constants::METHOD_TX_ROLLBACK => new Protocol\TxRollbackFrame, + Constants::METHOD_TX_ROLLBACK_OK => new Protocol\TxRollbackOkFrame, + default => throw new Exception\MethodInvalid(Constants::CLASS_TX, $methodId), + }; } - + /** - * @param int $methodId - * @param Buffer $buffer - * - * @return Protocol\MethodFrame + * @throws \PHPinnacle\Ridge\Exception\MethodInvalid + * @throws \PHPinnacle\Buffer\BufferOverflow */ private function consumeConfirmFrame(int $methodId, Buffer $buffer): Protocol\MethodFrame { - switch ($methodId) { - case Constants::METHOD_CONFIRM_SELECT: - return Protocol\ConfirmSelectFrame::unpack($buffer); - case Constants::METHOD_CONFIRM_SELECT_OK: - return new Protocol\ConfirmSelectOkFrame; - default: - throw new Exception\MethodInvalid(Constants::CLASS_CONFIRM, $methodId); - } + return match ($methodId) { + Constants::METHOD_CONFIRM_SELECT => Protocol\ConfirmSelectFrame::unpack($buffer), + Constants::METHOD_CONFIRM_SELECT_OK => new Protocol\ConfirmSelectOkFrame, + default => throw new Exception\MethodInvalid(Constants::CLASS_CONFIRM, $methodId), + }; } } diff --git a/src/Properties.php b/src/Properties.php index 684c481..344b711 100644 --- a/src/Properties.php +++ b/src/Properties.php @@ -14,7 +14,7 @@ final class Properties { - const UNKNOWN = 'unknown'; + public const UNKNOWN = 'unknown'; /** * @var string @@ -44,8 +44,9 @@ final class Properties * direct_reply_to * * @var bool[] + * @psalm-var array */ - private $capabilities = []; + private $capabilities; /** * @var int @@ -58,23 +59,23 @@ final class Properties private $maxFrame = 0xFFFF; /** - * @param string $platform - * @param string $product - * @param string $version - * @param array $capabilities + * @psalm-param array $capabilities */ public function __construct(string $platform, string $product, string $version, array $capabilities) { - $this->platform = $platform; - $this->product = $product; - $this->version = $version; + $this->platform = $platform; + $this->product = $product; + $this->version = $version; $this->capabilities = $capabilities; } /** - * @param array $config - * - * @return self + * @psalm-param array{ + * platform: string, + * product: string, + * version: string, + * capabilities: array + * } $config */ public static function create(array $config): self { @@ -86,61 +87,37 @@ public static function create(array $config): self ); } - /** - * @param int $maxChannel - * @param int $maxFrame - */ public function tune(int $maxChannel, int $maxFrame): void { $this->maxChannel = $maxChannel; - $this->maxFrame = $maxFrame; + $this->maxFrame = $maxFrame; } - /** - * @param string $ability - * - * @return bool - */ public function capable(string $ability): bool { return $this->capabilities[$ability] ?? false; } - /** - * @return string - */ public function platform(): string { return $this->platform; } - /** - * @return string - */ public function product(): string { return $this->product; } - /** - * @return string - */ public function version(): string { return $this->version; } - /** - * @return int - */ public function maxFrame(): int { return $this->maxFrame; } - /** - * @return int - */ public function maxChannel(): int { return $this->maxChannel; diff --git a/src/Protocol/AbstractFrame.php b/src/Protocol/AbstractFrame.php index 850c389..c87d7ca 100644 --- a/src/Protocol/AbstractFrame.php +++ b/src/Protocol/AbstractFrame.php @@ -15,36 +15,30 @@ abstract class AbstractFrame { /** - * @var int + * @var int|null */ public $type; /** - * @var int + * @var int|null */ public $channel; /** - * @var int + * @var int|null */ public $size; /** - * @var string + * @var string|null */ public $payload; - /** - * @param int $type - * @param int $channel - * @param int $size - * @param string $payload - */ - public function __construct(int $type = null, int $channel = null, int $size = null, string $payload = null) + public function __construct(?int $type = null, ?int $channel = null, ?int $size = null, ?string $payload = null) { - $this->type = $type; + $this->type = $type; $this->channel = $channel; - $this->size = $size; + $this->size = $size; $this->payload = $payload; } } \ No newline at end of file diff --git a/src/Protocol/AcknowledgmentFrame.php b/src/Protocol/AcknowledgmentFrame.php index 2ea4412..01370e2 100644 --- a/src/Protocol/AcknowledgmentFrame.php +++ b/src/Protocol/AcknowledgmentFrame.php @@ -18,7 +18,7 @@ abstract class AcknowledgmentFrame extends MethodFrame public $deliveryTag = 0; /** - * @var int + * @var bool */ public $multiple = false; } diff --git a/src/Protocol/BasicAckFrame.php b/src/Protocol/BasicAckFrame.php index 554b42e..cde5d0d 100644 --- a/src/Protocol/BasicAckFrame.php +++ b/src/Protocol/BasicAckFrame.php @@ -19,30 +19,25 @@ public function __construct() { parent::__construct(Constants::CLASS_BASIC, Constants::METHOD_BASIC_ACK); } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; $self->deliveryTag = $buffer->consumeInt64(); - [$self->multiple] = $buffer->consumeBits(1); - + [$self->multiple] = $buffer->consumeBits(1); + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); $buffer->appendInt64($this->deliveryTag); $buffer->appendBits([$this->multiple]); - + return $buffer; } } diff --git a/src/Protocol/BasicCancelFrame.php b/src/Protocol/BasicCancelFrame.php index a683010..261ce40 100644 --- a/src/Protocol/BasicCancelFrame.php +++ b/src/Protocol/BasicCancelFrame.php @@ -29,30 +29,25 @@ public function __construct() { parent::__construct(Constants::CLASS_BASIC, Constants::METHOD_BASIC_CANCEL); } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; $self->consumerTag = $buffer->consumeString(); - [$self->nowait] = $buffer->consumeBits(1); - + [$self->nowait] = $buffer->consumeBits(1); + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); $buffer->appendString($this->consumerTag); $buffer->appendBits([$this->nowait]); - + return $buffer; } } diff --git a/src/Protocol/BasicCancelOkFrame.php b/src/Protocol/BasicCancelOkFrame.php index 9f5d980..25f4ad2 100644 --- a/src/Protocol/BasicCancelOkFrame.php +++ b/src/Protocol/BasicCancelOkFrame.php @@ -19,33 +19,28 @@ class BasicCancelOkFrame extends MethodFrame * @var string */ public $consumerTag; - + public function __construct() { parent::__construct(Constants::CLASS_BASIC, Constants::METHOD_BASIC_CANCEL_OK); } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; $self->consumerTag = $buffer->consumeString(); - + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); $buffer->appendString($this->consumerTag); - + return $buffer; } } diff --git a/src/Protocol/BasicConsumeFrame.php b/src/Protocol/BasicConsumeFrame.php index a27efe4..36d2227 100644 --- a/src/Protocol/BasicConsumeFrame.php +++ b/src/Protocol/BasicConsumeFrame.php @@ -59,29 +59,24 @@ public function __construct() { parent::__construct(Constants::CLASS_BASIC, Constants::METHOD_BASIC_CONSUME); } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; - $self->reserved1 = $buffer->consumeInt16(); - $self->queue = $buffer->consumeString(); + $self->reserved1 = $buffer->consumeInt16(); + $self->queue = $buffer->consumeString(); $self->consumerTag = $buffer->consumeString(); - + [$self->noLocal, $self->noAck, $self->exclusive, $self->nowait] = $buffer->consumeBits(4); - + $self->arguments = $buffer->consumeTable(); - + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); @@ -90,7 +85,7 @@ public function pack(): Buffer $buffer->appendString($this->consumerTag); $buffer->appendBits([$this->noLocal, $this->noAck, $this->exclusive, $this->nowait]); $buffer->appendTable($this->arguments); - + return $buffer; } } diff --git a/src/Protocol/BasicConsumeOkFrame.php b/src/Protocol/BasicConsumeOkFrame.php index 5781b8b..5d53636 100644 --- a/src/Protocol/BasicConsumeOkFrame.php +++ b/src/Protocol/BasicConsumeOkFrame.php @@ -24,28 +24,23 @@ public function __construct() { parent::__construct(Constants::CLASS_BASIC, Constants::METHOD_BASIC_CONSUME_OK); } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; $self->consumerTag = $buffer->consumeString(); - + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); $buffer->appendString($this->consumerTag); - + return $buffer; } } diff --git a/src/Protocol/BasicDeliverFrame.php b/src/Protocol/BasicDeliverFrame.php index 7c0f886..3717575 100644 --- a/src/Protocol/BasicDeliverFrame.php +++ b/src/Protocol/BasicDeliverFrame.php @@ -19,32 +19,27 @@ class BasicDeliverFrame extends MessageFrame * @var string */ public $consumerTag; - + public function __construct() { parent::__construct(Constants::CLASS_BASIC, Constants::METHOD_BASIC_DELIVER); } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; - $self->consumerTag = $buffer->consumeString(); - $self->deliveryTag = $buffer->consumeInt64(); + $self->consumerTag = $buffer->consumeString(); + $self->deliveryTag = $buffer->consumeInt64(); [$self->redelivered] = $buffer->consumeBits(1); - $self->exchange = $buffer->consumeString(); - $self->routingKey = $buffer->consumeString(); - + $self->exchange = $buffer->consumeString(); + $self->routingKey = $buffer->consumeString(); + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); @@ -53,7 +48,7 @@ public function pack(): Buffer $buffer->appendBits([$this->redelivered]); $buffer->appendString($this->exchange); $buffer->appendString($this->routingKey); - + return $buffer; } } diff --git a/src/Protocol/BasicGetEmptyFrame.php b/src/Protocol/BasicGetEmptyFrame.php index 6c89baa..dfc3a26 100644 --- a/src/Protocol/BasicGetEmptyFrame.php +++ b/src/Protocol/BasicGetEmptyFrame.php @@ -19,33 +19,28 @@ class BasicGetEmptyFrame extends MethodFrame * @var string */ public $clusterId = ''; - + public function __construct() { parent::__construct(Constants::CLASS_BASIC, Constants::METHOD_BASIC_GET_EMPTY); } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; $self->clusterId = $buffer->consumeString(); - + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); $buffer->appendString($this->clusterId); - + return $buffer; } } diff --git a/src/Protocol/BasicGetFrame.php b/src/Protocol/BasicGetFrame.php index 9320b1c..7f205fe 100644 --- a/src/Protocol/BasicGetFrame.php +++ b/src/Protocol/BasicGetFrame.php @@ -29,37 +29,32 @@ class BasicGetFrame extends MethodFrame * @var bool */ public $noAck = false; - + public function __construct() { parent::__construct(Constants::CLASS_BASIC, Constants::METHOD_BASIC_GET); } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; $self->reserved1 = $buffer->consumeInt16(); - $self->queue = $buffer->consumeString(); - [$self->noAck] = $buffer->consumeBits(1); - + $self->queue = $buffer->consumeString(); + [$self->noAck] = $buffer->consumeBits(1); + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); $buffer->appendInt16($this->reserved1); $buffer->appendString($this->queue); $buffer->appendBits([$this->noAck]); - + return $buffer; } } diff --git a/src/Protocol/BasicGetOkFrame.php b/src/Protocol/BasicGetOkFrame.php index cb4a124..4a8099b 100644 --- a/src/Protocol/BasicGetOkFrame.php +++ b/src/Protocol/BasicGetOkFrame.php @@ -19,32 +19,27 @@ class BasicGetOkFrame extends MessageFrame * @var int */ public $messageCount; - + public function __construct() { parent::__construct(Constants::CLASS_BASIC, Constants::METHOD_BASIC_GET_OK); } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; - $self->deliveryTag = $buffer->consumeInt64(); + $self->deliveryTag = $buffer->consumeInt64(); [$self->redelivered] = $buffer->consumeBits(1); - $self->exchange = $buffer->consumeString(); - $self->routingKey = $buffer->consumeString(); - $self->messageCount = $buffer->consumeInt32(); - + $self->exchange = $buffer->consumeString(); + $self->routingKey = $buffer->consumeString(); + $self->messageCount = $buffer->consumeInt32(); + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); @@ -53,7 +48,7 @@ public function pack(): Buffer $buffer->appendString($this->exchange); $buffer->appendString($this->routingKey); $buffer->appendInt32($this->messageCount); - + return $buffer; } } diff --git a/src/Protocol/BasicNackFrame.php b/src/Protocol/BasicNackFrame.php index f989388..467952f 100644 --- a/src/Protocol/BasicNackFrame.php +++ b/src/Protocol/BasicNackFrame.php @@ -24,31 +24,26 @@ public function __construct() { parent::__construct(Constants::CLASS_BASIC, Constants::METHOD_BASIC_NACK); } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; $self->deliveryTag = $buffer->consumeInt64(); - + [$self->multiple, $self->requeue] = $buffer->consumeBits(2); - + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); $buffer->appendInt64($this->deliveryTag); $buffer->appendBits([$this->multiple, $this->requeue]); - + return $buffer; } } diff --git a/src/Protocol/BasicPublishFrame.php b/src/Protocol/BasicPublishFrame.php index 8905481..a418837 100644 --- a/src/Protocol/BasicPublishFrame.php +++ b/src/Protocol/BasicPublishFrame.php @@ -39,32 +39,27 @@ class BasicPublishFrame extends MethodFrame * @var bool */ public $immediate = false; - + public function __construct() { parent::__construct(Constants::CLASS_BASIC, Constants::METHOD_BASIC_PUBLISH); } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; - $self->reserved1 = $buffer->consumeInt16(); - $self->exchange = $buffer->consumeString(); + $self->reserved1 = $buffer->consumeInt16(); + $self->exchange = $buffer->consumeString(); $self->routingKey = $buffer->consumeString(); - + [$self->mandatory, $self->immediate] = $buffer->consumeBits(2); - + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); @@ -72,7 +67,7 @@ public function pack(): Buffer $buffer->appendString($this->exchange); $buffer->appendString($this->routingKey); $buffer->appendBits([$this->mandatory, $this->immediate]); - + return $buffer; } } diff --git a/src/Protocol/BasicQosFrame.php b/src/Protocol/BasicQosFrame.php index 573f11c..71795cb 100644 --- a/src/Protocol/BasicQosFrame.php +++ b/src/Protocol/BasicQosFrame.php @@ -29,37 +29,32 @@ class BasicQosFrame extends MethodFrame * @var bool */ public $global = false; - + public function __construct() { parent::__construct(Constants::CLASS_BASIC, Constants::METHOD_BASIC_QOS); } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; - $self->prefetchSize = $buffer->consumeInt32(); + $self->prefetchSize = $buffer->consumeInt32(); $self->prefetchCount = $buffer->consumeInt16(); - [$self->global] = $buffer->consumeBits(1); - + [$self->global] = $buffer->consumeBits(1); + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); $buffer->appendInt32($this->prefetchSize); $buffer->appendInt16($this->prefetchCount); $buffer->appendBits([$this->global]); - + return $buffer; } } diff --git a/src/Protocol/BasicRecoverAsyncFrame.php b/src/Protocol/BasicRecoverAsyncFrame.php index 711c7ab..9e65159 100644 --- a/src/Protocol/BasicRecoverAsyncFrame.php +++ b/src/Protocol/BasicRecoverAsyncFrame.php @@ -19,33 +19,28 @@ class BasicRecoverAsyncFrame extends MethodFrame * @var bool */ public $requeue = false; - + public function __construct() { parent::__construct(Constants::CLASS_BASIC, Constants::METHOD_BASIC_RECOVER_ASYNC); } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; [$self->requeue] = $buffer->consumeBits(1); - + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); $buffer->appendBits([$this->requeue]); - + return $buffer; } } diff --git a/src/Protocol/BasicRecoverFrame.php b/src/Protocol/BasicRecoverFrame.php index d4bdd0f..859f2ca 100644 --- a/src/Protocol/BasicRecoverFrame.php +++ b/src/Protocol/BasicRecoverFrame.php @@ -19,33 +19,28 @@ class BasicRecoverFrame extends MethodFrame * @var bool */ public $requeue = false; - + public function __construct() { parent::__construct(Constants::CLASS_BASIC, Constants::METHOD_BASIC_RECOVER); } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; [$self->requeue] = $buffer->consumeBits(1); - + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); $buffer->appendBits([$this->requeue]); - + return $buffer; } } diff --git a/src/Protocol/BasicRejectFrame.php b/src/Protocol/BasicRejectFrame.php index 8d0b593..63aed25 100644 --- a/src/Protocol/BasicRejectFrame.php +++ b/src/Protocol/BasicRejectFrame.php @@ -26,28 +26,23 @@ public function __construct() } /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; $self->deliveryTag = $buffer->consumeInt64(); - [$self->requeue] = $buffer->consumeBits(1); - + [$self->requeue] = $buffer->consumeBits(1); + return $self; } - /** - * @return Buffer - */ public function pack(): Buffer { $buffer = parent::pack(); $buffer->appendInt64($this->deliveryTag); $buffer->appendBits([$this->requeue]); - + return $buffer; } } diff --git a/src/Protocol/BasicReturnFrame.php b/src/Protocol/BasicReturnFrame.php index 4dcd0cb..f30a8a2 100644 --- a/src/Protocol/BasicReturnFrame.php +++ b/src/Protocol/BasicReturnFrame.php @@ -34,31 +34,26 @@ class BasicReturnFrame extends MethodFrame * @var string */ public $routingKey; - + public function __construct() { parent::__construct(Constants::CLASS_BASIC, Constants::METHOD_BASIC_RETURN); } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; - $self->replyCode = $buffer->consumeInt16(); - $self->replyText = $buffer->consumeString(); - $self->exchange = $buffer->consumeString(); + $self->replyCode = $buffer->consumeInt16(); + $self->replyText = $buffer->consumeString(); + $self->exchange = $buffer->consumeString(); $self->routingKey = $buffer->consumeString(); - + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); @@ -66,7 +61,7 @@ public function pack(): Buffer $buffer->appendString($this->replyText); $buffer->appendString($this->exchange); $buffer->appendString($this->routingKey); - + return $buffer; } } diff --git a/src/Protocol/ChannelCloseFrame.php b/src/Protocol/ChannelCloseFrame.php index 9c27987..e99fa72 100644 --- a/src/Protocol/ChannelCloseFrame.php +++ b/src/Protocol/ChannelCloseFrame.php @@ -34,32 +34,27 @@ class ChannelCloseFrame extends MethodFrame * @var int */ public $closeMethodId; - + public function __construct() { parent::__construct(Constants::CLASS_CHANNEL, Constants::METHOD_CHANNEL_CLOSE); } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; - - $self->replyCode = $buffer->consumeInt16(); - $self->replyText = $buffer->consumeString(); - $self->closeClassId = $buffer->consumeInt16(); + + $self->replyCode = $buffer->consumeInt16(); + $self->replyText = $buffer->consumeString(); + $self->closeClassId = $buffer->consumeInt16(); $self->closeMethodId = $buffer->consumeInt16(); - + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); @@ -67,7 +62,7 @@ public function pack(): Buffer $buffer->appendString($this->replyText); $buffer->appendInt16($this->closeClassId); $buffer->appendInt16($this->closeMethodId); - + return $buffer; } } diff --git a/src/Protocol/ChannelFlowFrame.php b/src/Protocol/ChannelFlowFrame.php index 9ef592e..7998ef7 100644 --- a/src/Protocol/ChannelFlowFrame.php +++ b/src/Protocol/ChannelFlowFrame.php @@ -24,23 +24,18 @@ public function __construct() { parent::__construct(Constants::CLASS_CHANNEL, Constants::METHOD_CHANNEL_FLOW); } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; [$self->active] = $buffer->consumeBits(1); - + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); diff --git a/src/Protocol/ChannelFlowOkFrame.php b/src/Protocol/ChannelFlowOkFrame.php index c205a94..85c5954 100644 --- a/src/Protocol/ChannelFlowOkFrame.php +++ b/src/Protocol/ChannelFlowOkFrame.php @@ -24,28 +24,23 @@ public function __construct() { parent::__construct(Constants::CLASS_CHANNEL, Constants::METHOD_CHANNEL_FLOW_OK); } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; [$self->active] = $buffer->consumeBits(1); - + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); $buffer->appendBits([$this->active]); - + return $buffer; } } diff --git a/src/Protocol/ChannelOpenFrame.php b/src/Protocol/ChannelOpenFrame.php index b12af9f..1a19044 100644 --- a/src/Protocol/ChannelOpenFrame.php +++ b/src/Protocol/ChannelOpenFrame.php @@ -19,34 +19,29 @@ class ChannelOpenFrame extends MethodFrame * @var string */ public $outOfBand = ''; - + public function __construct() { parent::__construct(Constants::CLASS_CHANNEL, Constants::METHOD_CHANNEL_OPEN); } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; - + $self->outOfBand = $buffer->consumeString(); - + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); $buffer->appendString($this->outOfBand); - + return $buffer; } } diff --git a/src/Protocol/ChannelOpenOkFrame.php b/src/Protocol/ChannelOpenOkFrame.php index 76fad73..d01ab4e 100644 --- a/src/Protocol/ChannelOpenOkFrame.php +++ b/src/Protocol/ChannelOpenOkFrame.php @@ -19,33 +19,28 @@ class ChannelOpenOkFrame extends MethodFrame * @var string */ public $channelId = ''; - + public function __construct() { parent::__construct(Constants::CLASS_CHANNEL, Constants::METHOD_CHANNEL_OPEN_OK); } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; $self->channelId = $buffer->consumeText(); - + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); $buffer->appendText($this->channelId); - + return $buffer; } } diff --git a/src/Protocol/ConfirmSelectFrame.php b/src/Protocol/ConfirmSelectFrame.php index f3dd55d..5be8224 100644 --- a/src/Protocol/ConfirmSelectFrame.php +++ b/src/Protocol/ConfirmSelectFrame.php @@ -19,33 +19,28 @@ class ConfirmSelectFrame extends MethodFrame * @var bool */ public $nowait = false; - + public function __construct() { parent::__construct(Constants::CLASS_CONFIRM, Constants::METHOD_CONFIRM_SELECT); } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; [$self->nowait] = $buffer->consumeBits(1); - + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); $buffer->appendBits([$this->nowait]); - + return $buffer; } } diff --git a/src/Protocol/ConnectionBlockedFrame.php b/src/Protocol/ConnectionBlockedFrame.php index e33426a..e5b0614 100644 --- a/src/Protocol/ConnectionBlockedFrame.php +++ b/src/Protocol/ConnectionBlockedFrame.php @@ -23,31 +23,26 @@ class ConnectionBlockedFrame extends MethodFrame public function __construct() { parent::__construct(Constants::CLASS_CONNECTION, Constants::METHOD_CONNECTION_BLOCKED); - + $this->channel = Constants::CONNECTION_CHANNEL; } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; $self->reason = $buffer->consumeString(); - + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); $buffer->appendString($this->reason); - + return $buffer; } } diff --git a/src/Protocol/ConnectionCloseFrame.php b/src/Protocol/ConnectionCloseFrame.php index 815e4f1..b1ae8ce 100644 --- a/src/Protocol/ConnectionCloseFrame.php +++ b/src/Protocol/ConnectionCloseFrame.php @@ -38,29 +38,24 @@ class ConnectionCloseFrame extends MethodFrame public function __construct() { parent::__construct(Constants::CLASS_CONNECTION, Constants::METHOD_CONNECTION_CLOSE); - + $this->channel = Constants::CONNECTION_CHANNEL; } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; - $self->replyCode = $buffer->consumeInt16(); - $self->replyText = $buffer->consumeString(); - $self->closeClassId = $buffer->consumeInt16(); + $self->replyCode = $buffer->consumeInt16(); + $self->replyText = $buffer->consumeString(); + $self->closeClassId = $buffer->consumeInt16(); $self->closeMethodId = $buffer->consumeInt16(); - + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); @@ -68,7 +63,7 @@ public function pack(): Buffer $buffer->appendString($this->replyText); $buffer->appendInt16($this->closeClassId); $buffer->appendInt16($this->closeMethodId); - + return $buffer; } } diff --git a/src/Protocol/ConnectionOpenFrame.php b/src/Protocol/ConnectionOpenFrame.php index 663ddd0..03d6ec1 100644 --- a/src/Protocol/ConnectionOpenFrame.php +++ b/src/Protocol/ConnectionOpenFrame.php @@ -29,39 +29,34 @@ class ConnectionOpenFrame extends MethodFrame * @var bool */ public $insist = false; - + public function __construct() { parent::__construct(Constants::CLASS_CONNECTION, Constants::METHOD_CONNECTION_OPEN); - + $this->channel = Constants::CONNECTION_CHANNEL; } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; - $self->virtualHost = $buffer->consumeString(); - $self->capabilities = $buffer->consumeString(); - [$self->insist] = $buffer->consumeBits(1); - + $self->virtualHost = $buffer->consumeString(); + $self->capabilities = $buffer->consumeString(); + [$self->insist] = $buffer->consumeBits(1); + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); $buffer->appendString($this->virtualHost); $buffer->appendString($this->capabilities); $buffer->appendBits([$this->insist]); - + return $buffer; } } diff --git a/src/Protocol/ConnectionOpenOkFrame.php b/src/Protocol/ConnectionOpenOkFrame.php index 2f2e882..4121553 100644 --- a/src/Protocol/ConnectionOpenOkFrame.php +++ b/src/Protocol/ConnectionOpenOkFrame.php @@ -19,35 +19,30 @@ class ConnectionOpenOkFrame extends MethodFrame * @var string */ public $knownHosts = ''; - + public function __construct() { parent::__construct(Constants::CLASS_CONNECTION, Constants::METHOD_CONNECTION_OPEN_OK); - + $this->channel = Constants::CONNECTION_CHANNEL; } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; $self->knownHosts = $buffer->consumeString(); - + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); $buffer->appendString($this->knownHosts); - + return $buffer; } } diff --git a/src/Protocol/ConnectionSecureFrame.php b/src/Protocol/ConnectionSecureFrame.php index 8afdd4d..d94d4cf 100644 --- a/src/Protocol/ConnectionSecureFrame.php +++ b/src/Protocol/ConnectionSecureFrame.php @@ -19,35 +19,30 @@ class ConnectionSecureFrame extends MethodFrame * @var string */ public $challenge; - + public function __construct() { parent::__construct(Constants::CLASS_CONNECTION, Constants::METHOD_CONNECTION_SECURE); - + $this->channel = Constants::CONNECTION_CHANNEL; } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; $self->challenge = $buffer->consumeText(); - + return $self; } - /** - * @return Buffer - */ public function pack(): Buffer { $buffer = parent::pack(); $buffer->appendText($this->challenge); - + return $buffer; } } diff --git a/src/Protocol/ConnectionSecureOkFrame.php b/src/Protocol/ConnectionSecureOkFrame.php index 38928bb..1167f43 100644 --- a/src/Protocol/ConnectionSecureOkFrame.php +++ b/src/Protocol/ConnectionSecureOkFrame.php @@ -19,18 +19,16 @@ class ConnectionSecureOkFrame extends MethodFrame * @var string */ public $response; - + public function __construct() { parent::__construct(Constants::CLASS_CONNECTION, Constants::METHOD_CONNECTION_SECURE_OK); - + $this->channel = Constants::CONNECTION_CHANNEL; } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { @@ -39,10 +37,7 @@ public static function unpack(Buffer $buffer): self return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); diff --git a/src/Protocol/ConnectionStartFrame.php b/src/Protocol/ConnectionStartFrame.php index ff21ba8..4698590 100644 --- a/src/Protocol/ConnectionStartFrame.php +++ b/src/Protocol/ConnectionStartFrame.php @@ -27,8 +27,14 @@ class ConnectionStartFrame extends MethodFrame /** * @var array + * @psalm-var array{ + * platform: string, + * product: string, + * version: string, + * capabilities: array + * } */ - public $serverProperties = []; + public $serverProperties; /** * @var string @@ -39,34 +45,40 @@ class ConnectionStartFrame extends MethodFrame * @var string */ public $locales = 'en_US'; - + public function __construct() { parent::__construct(Constants::CLASS_CONNECTION, Constants::METHOD_CONNECTION_START); - + $this->channel = Constants::CONNECTION_CHANNEL; } /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; - $self->versionMajor = $buffer->consumeUint8(); - $self->versionMinor = $buffer->consumeUint8(); - $self->serverProperties = $buffer->consumeTable(); - $self->mechanisms = $buffer->consumeText(); - $self->locales = $buffer->consumeText(); - + $self->versionMajor = $buffer->consumeUint8(); + $self->versionMinor = $buffer->consumeUint8(); + + /** + * @psalm-var array{ + * platform: string, + * product: string, + * version: string, + * capabilities: array + * } $serverProperties + */ + $serverProperties = $buffer->consumeTable(); + + $self->serverProperties = $serverProperties; + $self->mechanisms = $buffer->consumeText(); + $self->locales = $buffer->consumeText(); + return $self; } - /** - * @return Buffer - */ public function pack(): Buffer { $buffer = parent::pack(); @@ -75,7 +87,7 @@ public function pack(): Buffer $buffer->appendTable($this->serverProperties); $buffer->appendText($this->mechanisms); $buffer->appendText($this->locales); - + return $buffer; } } diff --git a/src/Protocol/ConnectionStartOkFrame.php b/src/Protocol/ConnectionStartOkFrame.php index 585a575..f1de6e7 100644 --- a/src/Protocol/ConnectionStartOkFrame.php +++ b/src/Protocol/ConnectionStartOkFrame.php @@ -34,33 +34,28 @@ class ConnectionStartOkFrame extends MethodFrame * @var string */ public $locale = 'en_US'; - + public function __construct() { parent::__construct(Constants::CLASS_CONNECTION, Constants::METHOD_CONNECTION_START_OK); - + $this->channel = Constants::CONNECTION_CHANNEL; } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; $self->clientProperties = $buffer->consumeTable(); - $self->mechanism = $buffer->consumeString(); - $self->response = $buffer->consumeText(); - $self->locale = $buffer->consumeString(); - + $self->mechanism = $buffer->consumeString(); + $self->response = $buffer->consumeText(); + $self->locale = $buffer->consumeString(); + return $self; } - /** - * @return Buffer - */ public function pack(): Buffer { $buffer = parent::pack(); @@ -68,7 +63,7 @@ public function pack(): Buffer $buffer->appendString($this->mechanism); $buffer->appendText($this->response); $buffer->appendString($this->locale); - + return $buffer; } } diff --git a/src/Protocol/ConnectionTuneFrame.php b/src/Protocol/ConnectionTuneFrame.php index b434afd..d5e4d45 100644 --- a/src/Protocol/ConnectionTuneFrame.php +++ b/src/Protocol/ConnectionTuneFrame.php @@ -29,39 +29,34 @@ class ConnectionTuneFrame extends MethodFrame * @var int */ public $heartbeat = 0; - + public function __construct() { parent::__construct(Constants::CLASS_CONNECTION, Constants::METHOD_CONNECTION_TUNE); - + $this->channel = Constants::CONNECTION_CHANNEL; } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; $self->channelMax = $buffer->consumeInt16(); - $self->frameMax = $buffer->consumeInt32(); - $self->heartbeat = $buffer->consumeInt16(); - + $self->frameMax = $buffer->consumeInt32(); + $self->heartbeat = $buffer->consumeInt16(); + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); $buffer->appendInt16($this->channelMax); $buffer->appendInt32($this->frameMax); $buffer->appendInt16($this->heartbeat); - + return $buffer; } } diff --git a/src/Protocol/ConnectionTuneOkFrame.php b/src/Protocol/ConnectionTuneOkFrame.php index 7f6e7b8..9dc5fef 100644 --- a/src/Protocol/ConnectionTuneOkFrame.php +++ b/src/Protocol/ConnectionTuneOkFrame.php @@ -29,39 +29,34 @@ class ConnectionTuneOkFrame extends MethodFrame * @var int */ public $heartbeat = 0; - + public function __construct() { parent::__construct(Constants::CLASS_CONNECTION, Constants::METHOD_CONNECTION_TUNE_OK); - + $this->channel = Constants::CONNECTION_CHANNEL; } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; $self->channelMax = $buffer->consumeInt16(); - $self->frameMax = $buffer->consumeInt32(); - $self->heartbeat = $buffer->consumeInt16(); - + $self->frameMax = $buffer->consumeInt32(); + $self->heartbeat = $buffer->consumeInt16(); + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); $buffer->appendInt16($this->channelMax); $buffer->appendInt32($this->frameMax); $buffer->appendInt16($this->heartbeat); - + return $buffer; } } diff --git a/src/Protocol/ContentBodyFrame.php b/src/Protocol/ContentBodyFrame.php index f0e188c..a2d6150 100644 --- a/src/Protocol/ContentBodyFrame.php +++ b/src/Protocol/ContentBodyFrame.php @@ -14,7 +14,7 @@ class ContentBodyFrame extends AbstractFrame { - public function __construct($channel = null, $payloadSize = null, $payload = null) + public function __construct(?int $channel = null, ?int $payloadSize = null, ?string $payload = null) { parent::__construct(Constants::FRAME_BODY, $channel, $payloadSize, $payload); } diff --git a/src/Protocol/ContentHeaderFrame.php b/src/Protocol/ContentHeaderFrame.php index 55f0a03..bc4366d 100644 --- a/src/Protocol/ContentHeaderFrame.php +++ b/src/Protocol/ContentHeaderFrame.php @@ -15,22 +15,20 @@ class ContentHeaderFrame extends AbstractFrame { - const - FLAG_CONTENT_TYPE = 0x8000, - FLAG_CONTENT_ENCODING = 0x4000, - FLAG_HEADERS = 0x2000, - FLAG_DELIVERY_MODE = 0x1000, - FLAG_PRIORITY = 0x0800, - FLAG_CORRELATION_ID = 0x0400, - FLAG_REPLY_TO = 0x0200, - FLAG_EXPIRATION = 0x0100, - FLAG_MESSAGE_ID = 0x0080, - FLAG_TIMESTAMP = 0x0040, - FLAG_TYPE = 0x0020, - FLAG_USER_ID = 0x0010, - FLAG_APP_ID = 0x0008, - FLAG_CLUSTER_ID = 0x0004 - ; + private const FLAG_CONTENT_TYPE = 0x8000; + private const FLAG_CONTENT_ENCODING = 0x4000; + private const FLAG_HEADERS = 0x2000; + private const FLAG_DELIVERY_MODE = 0x1000; + private const FLAG_PRIORITY = 0x0800; + private const FLAG_CORRELATION_ID = 0x0400; + private const FLAG_REPLY_TO = 0x0200; + private const FLAG_EXPIRATION = 0x0100; + private const FLAG_MESSAGE_ID = 0x0080; + private const FLAG_TIMESTAMP = 0x0040; + private const FLAG_TYPE = 0x0020; + private const FLAG_USER_ID = 0x0010; + private const FLAG_APP_ID = 0x0008; + private const FLAG_CLUSTER_ID = 0x0004; /** * @var int @@ -53,12 +51,12 @@ class ContentHeaderFrame extends AbstractFrame public $flags = 0; /** - * @var string + * @var string|null */ public $contentType; /** - * @var string + * @var string|null */ public $contentEncoding; @@ -68,57 +66,57 @@ class ContentHeaderFrame extends AbstractFrame public $headers; /** - * @var int + * @var int|null */ public $deliveryMode; /** - * @var int + * @var int|null */ public $priority; /** - * @var string + * @var string|null */ public $correlationId; /** - * @var string + * @var string|null */ public $replyTo; /** - * @var string + * @var string|null */ public $expiration; /** - * @var string + * @var string|null */ public $messageId; /** - * @var \DateTimeInterface + * @var \DateTimeInterface|null */ public $timestamp; /** - * @var string + * @var string|null */ public $typeHeader; /** - * @var string + * @var string|null */ public $userId; /** - * @var string + * @var string|null */ public $appId; /** - * @var string + * @var string|null */ public $clusterId; @@ -128,156 +126,147 @@ public function __construct() } /** - * @param Buffer $buffer - * - * @return ContentHeaderFrame + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; - $self->classId = $buffer->consumeUint16(); - $self->weight = $buffer->consumeUint16(); + $self->classId = $buffer->consumeUint16(); + $self->weight = $buffer->consumeUint16(); $self->bodySize = $buffer->consumeUint64(); - $self->flags = $flags = $buffer->consumeUint16(); - + $self->flags = $flags = $buffer->consumeUint16(); + if ($flags & self::FLAG_CONTENT_TYPE) { $self->contentType = $buffer->consumeString(); } - + if ($flags & self::FLAG_CONTENT_ENCODING) { $self->contentEncoding = $buffer->consumeString(); } - + if ($flags & self::FLAG_HEADERS) { $self->headers = $buffer->consumeTable(); } - + if ($flags & self::FLAG_DELIVERY_MODE) { $self->deliveryMode = $buffer->consumeUint8(); } - + if ($flags & self::FLAG_PRIORITY) { $self->priority = $buffer->consumeUint8(); } - + if ($flags & self::FLAG_CORRELATION_ID) { $self->correlationId = $buffer->consumeString(); } - + if ($flags & self::FLAG_REPLY_TO) { $self->replyTo = $buffer->consumeString(); } - + if ($flags & self::FLAG_EXPIRATION) { $self->expiration = $buffer->consumeString(); } - + if ($flags & self::FLAG_MESSAGE_ID) { $self->messageId = $buffer->consumeString(); } - + if ($flags & self::FLAG_TIMESTAMP) { $self->timestamp = $buffer->consumeTimestamp(); } - + if ($flags & self::FLAG_TYPE) { $self->typeHeader = $buffer->consumeString(); } - + if ($flags & self::FLAG_USER_ID) { $self->userId = $buffer->consumeString(); } - + if ($flags & self::FLAG_APP_ID) { $self->appId = $buffer->consumeString(); } - + if ($flags & self::FLAG_CLUSTER_ID) { $self->clusterId = $buffer->consumeString(); } - + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = new Buffer; $buffer ->appendUint16($this->classId) ->appendUint16($this->weight) - ->appendUint64($this->bodySize) - ; - + ->appendUint64($this->bodySize); + $flags = $this->flags; - + $buffer->appendUint16($flags); - - if ($flags & ContentHeaderFrame::FLAG_CONTENT_TYPE) { + + if ($flags & self::FLAG_CONTENT_TYPE && $this->contentType !== null) { $buffer->appendString($this->contentType); } - - if ($flags & ContentHeaderFrame::FLAG_CONTENT_ENCODING) { + + if ($flags & self::FLAG_CONTENT_ENCODING && $this->contentEncoding !== null) { $buffer->appendString($this->contentEncoding); } - - if ($flags & ContentHeaderFrame::FLAG_HEADERS) { + + if ($flags & self::FLAG_HEADERS) { $buffer->appendTable($this->headers); } - - if ($flags & ContentHeaderFrame::FLAG_DELIVERY_MODE) { + + if ($flags & self::FLAG_DELIVERY_MODE && $this->deliveryMode !== null) { $buffer->appendUint8($this->deliveryMode); } - - if ($flags & ContentHeaderFrame::FLAG_PRIORITY) { + + if ($flags & self::FLAG_PRIORITY && $this->priority) { $buffer->appendUint8($this->priority); } - - if ($flags & ContentHeaderFrame::FLAG_CORRELATION_ID) { + + if ($flags & self::FLAG_CORRELATION_ID && $this->correlationId !== null) { $buffer->appendString($this->correlationId); } - - if ($flags & ContentHeaderFrame::FLAG_REPLY_TO) { + + if ($flags & self::FLAG_REPLY_TO && $this->replyTo !== null) { $buffer->appendString($this->replyTo); } - - if ($flags & ContentHeaderFrame::FLAG_EXPIRATION) { + + if ($flags & self::FLAG_EXPIRATION && $this->expiration !== null) { $buffer->appendString($this->expiration); } - - if ($flags & ContentHeaderFrame::FLAG_MESSAGE_ID) { + + if ($flags & self::FLAG_MESSAGE_ID && $this->messageId !== null) { $buffer->appendString($this->messageId); } - - if ($flags & ContentHeaderFrame::FLAG_TIMESTAMP) { + + if ($flags & self::FLAG_TIMESTAMP && $this->timestamp !== null) { $buffer->appendTimestamp($this->timestamp); } - - if ($flags & ContentHeaderFrame::FLAG_TYPE) { + + if ($flags & self::FLAG_TYPE && $this->typeHeader !== null) { $buffer->appendString($this->typeHeader); } - - if ($flags & ContentHeaderFrame::FLAG_USER_ID) { + + if ($flags & self::FLAG_USER_ID && $this->userId !== null) { $buffer->appendString($this->userId); } - - if ($flags & ContentHeaderFrame::FLAG_APP_ID) { + + if ($flags & self::FLAG_APP_ID && $this->appId !== null) { $buffer->appendString($this->appId); } - - if ($flags & ContentHeaderFrame::FLAG_CLUSTER_ID) { + + if ($flags & self::FLAG_CLUSTER_ID && $this->clusterId !== null) { $buffer->appendString($this->clusterId); } - + return $buffer; } - /** - * @return array - */ public function toArray(): array { $headers = $this->headers ?: []; diff --git a/src/Protocol/ExchangeBindFrame.php b/src/Protocol/ExchangeBindFrame.php index f5fb9b9..83bd50f 100644 --- a/src/Protocol/ExchangeBindFrame.php +++ b/src/Protocol/ExchangeBindFrame.php @@ -49,28 +49,23 @@ public function __construct() { parent::__construct(Constants::CLASS_EXCHANGE, Constants::METHOD_EXCHANGE_BIND); } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; - $self->reserved1 = $buffer->consumeInt16(); + $self->reserved1 = $buffer->consumeInt16(); $self->destination = $buffer->consumeString(); - $self->source = $buffer->consumeString(); - $self->routingKey = $buffer->consumeString(); - [$self->nowait] = $buffer->consumeBits(1); - $self->arguments = $buffer->consumeTable(); - + $self->source = $buffer->consumeString(); + $self->routingKey = $buffer->consumeString(); + [$self->nowait] = $buffer->consumeBits(1); + $self->arguments = $buffer->consumeTable(); + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); @@ -80,7 +75,7 @@ public function pack(): Buffer $buffer->appendString($this->routingKey); $buffer->appendBits([$this->nowait]); $buffer->appendTable($this->arguments); - + return $buffer; } } diff --git a/src/Protocol/ExchangeDeclareFrame.php b/src/Protocol/ExchangeDeclareFrame.php index 0016a17..dfafbcb 100644 --- a/src/Protocol/ExchangeDeclareFrame.php +++ b/src/Protocol/ExchangeDeclareFrame.php @@ -64,29 +64,24 @@ public function __construct() { parent::__construct(Constants::CLASS_EXCHANGE, Constants::METHOD_EXCHANGE_DECLARE); } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; - $self->reserved1 = $buffer->consumeInt16(); - $self->exchange = $buffer->consumeString(); + $self->reserved1 = $buffer->consumeInt16(); + $self->exchange = $buffer->consumeString(); $self->exchangeType = $buffer->consumeString(); [$self->passive, $self->durable, $self->autoDelete, $self->internal, $self->nowait] = $buffer->consumeBits(5); $self->arguments = $buffer->consumeTable(); - + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); @@ -95,7 +90,7 @@ public function pack(): Buffer $buffer->appendString($this->exchangeType); $buffer->appendBits([$this->passive, $this->durable, $this->autoDelete, $this->internal, $this->nowait]); $buffer->appendTable($this->arguments); - + return $buffer; } } diff --git a/src/Protocol/ExchangeDeleteFrame.php b/src/Protocol/ExchangeDeleteFrame.php index 9d19ca4..34307eb 100644 --- a/src/Protocol/ExchangeDeleteFrame.php +++ b/src/Protocol/ExchangeDeleteFrame.php @@ -39,34 +39,29 @@ public function __construct() { parent::__construct(Constants::CLASS_EXCHANGE, Constants::METHOD_EXCHANGE_DELETE); } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; - + $self->reserved1 = $buffer->consumeInt16(); - $self->exchange = $buffer->consumeString(); - + $self->exchange = $buffer->consumeString(); + [$self->ifUnused, $self->nowait] = $buffer->consumeBits(2); - + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); $buffer->appendInt16($this->reserved1); $buffer->appendString($this->exchange); $buffer->appendBits([$this->ifUnused, $this->nowait]); - + return $buffer; } } diff --git a/src/Protocol/ExchangeUnbindFrame.php b/src/Protocol/ExchangeUnbindFrame.php index 0daaaf9..1d59089 100644 --- a/src/Protocol/ExchangeUnbindFrame.php +++ b/src/Protocol/ExchangeUnbindFrame.php @@ -49,28 +49,23 @@ public function __construct() { parent::__construct(Constants::CLASS_EXCHANGE, Constants::METHOD_EXCHANGE_UNBIND); } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; - $self->reserved1 = $buffer->consumeInt16(); + $self->reserved1 = $buffer->consumeInt16(); $self->destination = $buffer->consumeString(); - $self->source = $buffer->consumeString(); - $self->routingKey = $buffer->consumeString(); - [$self->nowait] = $buffer->consumeBits(1); - $self->arguments = $buffer->consumeTable(); - + $self->source = $buffer->consumeString(); + $self->routingKey = $buffer->consumeString(); + [$self->nowait] = $buffer->consumeBits(1); + $self->arguments = $buffer->consumeTable(); + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); @@ -80,7 +75,7 @@ public function pack(): Buffer $buffer->appendString($this->routingKey); $buffer->appendBits([$this->nowait]); $buffer->appendTable($this->arguments); - + return $buffer; } } diff --git a/src/Protocol/MethodFrame.php b/src/Protocol/MethodFrame.php index d84c231..87248ae 100644 --- a/src/Protocol/MethodFrame.php +++ b/src/Protocol/MethodFrame.php @@ -16,37 +16,29 @@ class MethodFrame extends AbstractFrame { /** - * @var int + * @var int|null */ public $classId; /** - * @var int + * @var int|null */ public $methodId; - /** - * @param int $classId - * @param int $methodId - */ - public function __construct(int $classId = null, int $methodId = null) + public function __construct(?int $classId = null, ?int $methodId = null) { parent::__construct(Constants::FRAME_METHOD); - $this->classId = $classId; + $this->classId = $classId; $this->methodId = $methodId; } - /** - * @return Buffer - */ public function pack(): Buffer { $buffer = new Buffer; $buffer - ->appendUint16($this->classId) - ->appendUint16($this->methodId) - ; + ->appendUint16((int)$this->classId) + ->appendUint16((int)$this->methodId); return $buffer; } diff --git a/src/Protocol/QueueBindFrame.php b/src/Protocol/QueueBindFrame.php index 3424201..7525937 100644 --- a/src/Protocol/QueueBindFrame.php +++ b/src/Protocol/QueueBindFrame.php @@ -44,34 +44,28 @@ class QueueBindFrame extends MethodFrame * @var array */ public $arguments = []; - + public function __construct() { parent::__construct(Constants::CLASS_QUEUE, Constants::METHOD_QUEUE_BIND); - } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; - $self->reserved1 = $buffer->consumeInt16(); - $self->queue = $buffer->consumeString(); - $self->exchange = $buffer->consumeString(); + $self->reserved1 = $buffer->consumeInt16(); + $self->queue = $buffer->consumeString(); + $self->exchange = $buffer->consumeString(); $self->routingKey = $buffer->consumeString(); - [$self->nowait] = $buffer->consumeBits(1); - $self->arguments = $buffer->consumeTable(); - + [$self->nowait] = $buffer->consumeBits(1); + $self->arguments = $buffer->consumeTable(); + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); @@ -81,7 +75,7 @@ public function pack(): Buffer $buffer->appendString($this->routingKey); $buffer->appendBits([$this->nowait]); $buffer->appendTable($this->arguments); - + return $buffer; } } diff --git a/src/Protocol/QueueDeclareFrame.php b/src/Protocol/QueueDeclareFrame.php index 299fdf9..f4d7c43 100644 --- a/src/Protocol/QueueDeclareFrame.php +++ b/src/Protocol/QueueDeclareFrame.php @@ -59,28 +59,23 @@ public function __construct() { parent::__construct(Constants::CLASS_QUEUE, Constants::METHOD_QUEUE_DECLARE); } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; $self->reserved1 = $buffer->consumeInt16(); - $self->queue = $buffer->consumeString(); - + $self->queue = $buffer->consumeString(); + [$self->passive, $self->durable, $self->exclusive, $self->autoDelete, $self->nowait] = $buffer->consumeBits(5); - + $self->arguments = $buffer->consumeTable(); - + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); @@ -88,7 +83,7 @@ public function pack(): Buffer $buffer->appendString($this->queue); $buffer->appendBits([$this->passive, $this->durable, $this->exclusive, $this->autoDelete, $this->nowait]); $buffer->appendTable($this->arguments); - + return $buffer; } } diff --git a/src/Protocol/QueueDeclareOkFrame.php b/src/Protocol/QueueDeclareOkFrame.php index 589c72d..e225704 100644 --- a/src/Protocol/QueueDeclareOkFrame.php +++ b/src/Protocol/QueueDeclareOkFrame.php @@ -29,37 +29,32 @@ class QueueDeclareOkFrame extends MethodFrame * @var int */ public $consumerCount; - + public function __construct() { parent::__construct(Constants::CLASS_QUEUE, Constants::METHOD_QUEUE_DECLARE_OK); } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; - $self->queue = $buffer->consumeString(); - $self->messageCount = $buffer->consumeInt32(); + $self->queue = $buffer->consumeString(); + $self->messageCount = $buffer->consumeInt32(); $self->consumerCount = $buffer->consumeInt32(); return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); $buffer->appendString($this->queue); $buffer->appendInt32($this->messageCount); $buffer->appendInt32($this->consumerCount); - + return $buffer; } } diff --git a/src/Protocol/QueueDeleteFrame.php b/src/Protocol/QueueDeleteFrame.php index 57823d4..6317335 100644 --- a/src/Protocol/QueueDeleteFrame.php +++ b/src/Protocol/QueueDeleteFrame.php @@ -44,33 +44,28 @@ public function __construct() { parent::__construct(Constants::CLASS_QUEUE, Constants::METHOD_QUEUE_DELETE); } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; $self->reserved1 = $buffer->consumeInt16(); - $self->queue = $buffer->consumeString(); - + $self->queue = $buffer->consumeString(); + [$self->ifUnused, $self->ifEmpty, $self->nowait] = $buffer->consumeBits(3); - + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); $buffer->appendInt16($this->reserved1); $buffer->appendString($this->queue); $buffer->appendBits([$this->ifUnused, $this->ifEmpty, $this->nowait]); - + return $buffer; } } diff --git a/src/Protocol/QueueDeleteOkFrame.php b/src/Protocol/QueueDeleteOkFrame.php index 8d8de65..1018ade 100644 --- a/src/Protocol/QueueDeleteOkFrame.php +++ b/src/Protocol/QueueDeleteOkFrame.php @@ -24,28 +24,23 @@ public function __construct() { parent::__construct(Constants::CLASS_QUEUE, Constants::METHOD_QUEUE_DELETE_OK); } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; $self->messageCount = $buffer->consumeInt32(); - + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); $buffer->appendInt32($this->messageCount); - + return $buffer; } } diff --git a/src/Protocol/QueuePurgeFrame.php b/src/Protocol/QueuePurgeFrame.php index e1bd347..e320bcc 100644 --- a/src/Protocol/QueuePurgeFrame.php +++ b/src/Protocol/QueuePurgeFrame.php @@ -34,32 +34,27 @@ public function __construct() { parent::__construct(Constants::CLASS_QUEUE, Constants::METHOD_QUEUE_PURGE); } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; $self->reserved1 = $buffer->consumeInt16(); - $self->queue = $buffer->consumeString(); - [$self->nowait] = $buffer->consumeBits(1); - + $self->queue = $buffer->consumeString(); + [$self->nowait] = $buffer->consumeBits(1); + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); $buffer->appendInt16($this->reserved1); $buffer->appendString($this->queue); $buffer->appendBits([$this->nowait]); - + return $buffer; } } diff --git a/src/Protocol/QueuePurgeOkFrame.php b/src/Protocol/QueuePurgeOkFrame.php index c42018a..b4bc3ee 100644 --- a/src/Protocol/QueuePurgeOkFrame.php +++ b/src/Protocol/QueuePurgeOkFrame.php @@ -24,28 +24,23 @@ public function __construct() { parent::__construct(Constants::CLASS_QUEUE, Constants::METHOD_QUEUE_PURGE_OK); } - + /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; $self->messageCount = $buffer->consumeInt32(); - + return $self; } - - /** - * @return Buffer - */ + public function pack(): Buffer { $buffer = parent::pack(); $buffer->appendInt32($this->messageCount); - + return $buffer; } } diff --git a/src/Protocol/QueueUnbindFrame.php b/src/Protocol/QueueUnbindFrame.php index d9c4276..1b8e846 100644 --- a/src/Protocol/QueueUnbindFrame.php +++ b/src/Protocol/QueueUnbindFrame.php @@ -46,25 +46,20 @@ public function __construct() } /** - * @param Buffer $buffer - * - * @return self + * @throws \PHPinnacle\Buffer\BufferOverflow */ public static function unpack(Buffer $buffer): self { $self = new self; - $self->reserved1 = $buffer->consumeInt16(); - $self->queue = $buffer->consumeString(); - $self->exchange = $buffer->consumeString(); + $self->reserved1 = $buffer->consumeInt16(); + $self->queue = $buffer->consumeString(); + $self->exchange = $buffer->consumeString(); $self->routingKey = $buffer->consumeString(); - $self->arguments = $buffer->consumeTable(); - + $self->arguments = $buffer->consumeTable(); + return $self; } - /** - * @return Buffer - */ public function pack(): Buffer { $buffer = parent::pack(); @@ -73,7 +68,7 @@ public function pack(): Buffer $buffer->appendString($this->exchange); $buffer->appendString($this->routingKey); $buffer->appendTable($this->arguments); - + return $buffer; } } diff --git a/src/Queue.php b/src/Queue.php index 47c0394..0458b6c 100644 --- a/src/Queue.php +++ b/src/Queue.php @@ -29,37 +29,23 @@ final class Queue */ private $consumers; - /** - * @param string $name - * @param int $messages - * @param int $consumers - */ public function __construct(string $name, int $messages, int $consumers) { - $this->name = $name; - $this->messages = $messages; + $this->name = $name; + $this->messages = $messages; $this->consumers = $consumers; } - /** - * @return string - */ public function name(): string { return $this->name; } - /** - * @return int - */ public function messages(): int { return $this->messages; } - /** - * @return int - */ public function consumers(): int { return $this->consumers; diff --git a/tests/ConfigTest.php b/tests/ConfigTest.php index 4b90e65..c84852c 100644 --- a/tests/ConfigTest.php +++ b/tests/ConfigTest.php @@ -18,11 +18,11 @@ public function testCreate() { $config = new Config(); - self::assertSame('localhost', $config->host()); - self::assertSame(5672, $config->port()); - self::assertSame('/', $config->vhost()); - self::assertSame('guest', $config->user()); - self::assertSame('guest', $config->password()); + self::assertSame('localhost', $config->host); + self::assertSame(5672, $config->port); + self::assertSame('/', $config->vhost); + self::assertSame('guest', $config->user); + self::assertSame('guest', $config->pass); } public function testUri() @@ -38,20 +38,20 @@ public function testParse() { $config = Config::parse('amqp://user:pass@localhost:5672/test'); - self::assertSame('localhost', $config->host()); - self::assertSame(5672, $config->port()); - self::assertSame('test', $config->vhost()); - self::assertSame('user', $config->user()); - self::assertSame('pass', $config->password()); + self::assertSame('localhost', $config->host); + self::assertSame(5672, $config->port); + self::assertSame('test', $config->vhost); + self::assertSame('user', $config->user); + self::assertSame('pass', $config->pass); } public function testVhost() { - self::assertSame('test', Config::parse('amqp://localhost:5672/test')->vhost()); - self::assertSame('/', Config::parse('amqp://localhost:5672/')->vhost()); - self::assertSame('/', Config::parse('amqp://localhost:5672')->vhost()); - self::assertSame('test/', Config::parse('amqp://localhost:5672/test/')->vhost()); - self::assertSame('test/test', Config::parse('amqp://localhost:5672/test/test')->vhost()); - self::assertSame('test/test//', Config::parse('amqp://localhost:5672/test/test//')->vhost()); + self::assertSame('test', Config::parse('amqp://localhost:5672/test')->vhost); + self::assertSame('/', Config::parse('amqp://localhost:5672/')->vhost); + self::assertSame('/', Config::parse('amqp://localhost:5672')->vhost); + self::assertSame('test/', Config::parse('amqp://localhost:5672/test/')->vhost); + self::assertSame('test/test', Config::parse('amqp://localhost:5672/test/test')->vhost); + self::assertSame('test/test//', Config::parse('amqp://localhost:5672/test/test//')->vhost); } } diff --git a/tests/RidgeTest.php b/tests/RidgeTest.php index ded143e..03c6a48 100644 --- a/tests/RidgeTest.php +++ b/tests/RidgeTest.php @@ -32,12 +32,12 @@ protected static function assertPromise($value): void */ protected static function client(): Client { - if (!$dsn = \getenv('RIDGE_TEST_DSN')) { + if(!$dsn = \getenv('RIDGE_TEST_DSN')) + { self::markTestSkipped('No test dsn! Please set RIDGE_TEST_DSN environment variable.'); } $config = Config::parse($dsn); - $config->heartbeat(0); return new Client($config); }