From 105f5188b4754083b08b8a47e5287b87158e8a55 Mon Sep 17 00:00:00 2001 From: alexmerlin Date: Tue, 26 Aug 2025 14:16:19 +0300 Subject: [PATCH 1/2] Release preparations Signed-off-by: alexmerlin --- README.md | 12 ++--- composer.json | 8 ++-- config/autoload/local.php.dist | 12 ++--- config/autoload/log.local.php.dist | 10 +++-- config/autoload/messenger.local.php.dist | 35 ++++++++------- config/autoload/swoole.local.php.dist | 15 ++++--- daemon/messenger.service | 2 +- daemon/swoole.service | 2 +- phpcs.xml | 2 +- phpstan.neon | 2 + public/index.php | 16 ++++--- src/App/ConfigProvider.php | 28 ++++++------ src/App/Message/MessageHandler.php | 15 ++++--- .../Command/Factory/StopCommandFactory.php | 6 +++ .../Command/GetFailedMessagesCommand.php | 21 +++++---- .../Command/GetProcessedMessagesCommand.php | 21 +++++---- src/Swoole/Command/IsRunningTrait.php | 2 +- src/Swoole/Command/StartCommand.php | 14 +++--- src/Swoole/Command/StopCommand.php | 16 +++---- src/Swoole/ConfigProvider.php | 5 +-- src/Swoole/Delegators/TCPServerDelegator.php | 45 +++++++++++-------- src/Swoole/PidManager.php | 4 +- src/Swoole/PidManagerFactory.php | 7 +++ src/Swoole/ServerFactory.php | 7 ++- test/App/Message/MessageHandlerTest.php | 17 ++++--- test/App/Message/MessageTest.php | 4 +- .../Command/GetDataFromLogsCommandTest.php | 22 ++++----- .../Command/GetQueuedMessagesCommandTest.php | 7 ++- test/Swoole/Command/StopCommandTest.php | 4 +- test/Swoole/Delegators/DummySwooleServer.php | 12 ++++- .../Delegators/TCPServerDelegatorTest.php | 42 +++++++++++++---- ...dStaticResourceMiddlewareExceptionTest.php | 3 +- test/Swoole/PidManagerFactoryTest.php | 9 ++-- test/Swoole/ServerFactoryTest.php | 20 ++++++--- 34 files changed, 270 insertions(+), 177 deletions(-) diff --git a/README.md b/README.md index 3d79801..2d384ad 100644 --- a/README.md +++ b/README.md @@ -3,13 +3,13 @@ > [!IMPORTANT] > Dotkernel component used to queue tasks to be processed asynchronously based on [netglue/laminas-messenger](https://github.com/netglue/laminas-messenger) - A queue system is a vital component in modern web applications that enables the decoupling of certain tasks from the regular request-response cycle. +A queue system is a vital part in modern web applications that enables the decoupling of certain tasks from the regular request-response cycle. - This is especially useful for time-consuming and resource-intensive operations which are thus handled asynchronously by background workers on a separate system. +This is especially useful for time-consuming and resource-intensive operations which are thus handled asynchronously by background workers on a separate system. -The greatest benefit is to application responsiveness which allows faster execution, while the heavy lifting is scheduled in the queue based on available resources. +The greatest benefit is to application responsiveness, which allows faster execution, while the heavy lifting is scheduled in the queue based on available resources. - The queue system uses logs to ensure maintainability and implements retry features for reliability and stability. +The queue system uses logs to ensure maintainability and implements retry features for reliability and stability. ![Queue process](https://docs.dotkernel.org/img/queue/schema.png) @@ -28,10 +28,6 @@ The greatest benefit is to application responsiveness which allows faster execut [![Qodana](https://github.com/dotkernel/queue/actions/workflows/qodana_code_quality.yml/badge.svg?branch=main)](https://github.com/dotkernel/queue/actions/workflows/qodana_code_quality.yml) [![PHPStan](https://github.com/dotkernel/queue/actions/workflows/static-analysis.yml/badge.svg?branch=main)](https://github.com/dotkernel/queue/actions/workflows/static-analysis.yml) -## Installation - -> Until we have a compiled documentation, read the files from /doc/book/v1 folder - ## Documentation Documentation is available at: https://docs.dotkernel.org/queue-documentation diff --git a/composer.json b/composer.json index cc845be..46ae5ed 100644 --- a/composer.json +++ b/composer.json @@ -55,12 +55,12 @@ }, "require-dev": { "laminas/laminas-coding-standard": "^3.0", - "phpunit/phpunit": "^10.5.45", - "roave/security-advisories": "dev-master", - "swoole/ide-helper": "~5.0.0", "phpstan/phpstan": "^2.0", "phpstan/phpstan-doctrine": "^2.0", - "phpstan/phpstan-phpunit": "^2.0" + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^10.5.45", + "roave/security-advisories": "dev-master", + "swoole/ide-helper": "~5.0.0" }, "autoload": { "psr-4": { diff --git a/config/autoload/local.php.dist b/config/autoload/local.php.dist index 429a793..3de5fb1 100644 --- a/config/autoload/local.php.dist +++ b/config/autoload/local.php.dist @@ -9,7 +9,7 @@ declare(strict_types=1); -$baseUrl = 'http://queue.dotkernel.net'; +$baseUrl = 'https://queue.dotkernel.net'; $databases = [ 'default' => [ @@ -43,13 +43,13 @@ return [ 'protocol' => 'tcp', 'host' => 'localhost', 'port' => '8556', - 'eof' => "\n", + 'eof' => PHP_EOL, ], ], //delay time until the message is added back to the queue if an error occurs during processing 'fail-safe' => [ - 'first_retry' => 3600000, // 1h - 'second_retry' => 43200000, // 12h - 'third_retry' => 86400000, // 24h - ], + 'first_retry' => 3600000, // 1h + 'second_retry' => 43200000, // 12h + 'third_retry' => 86400000, // 24h + ], ]; diff --git a/config/autoload/log.local.php.dist b/config/autoload/log.local.php.dist index 1422cc8..e88e592 100644 --- a/config/autoload/log.local.php.dist +++ b/config/autoload/log.local.php.dist @@ -1,5 +1,7 @@ [ 'writers' => [ 'FileWriter' => [ - 'name' => 'stream', - 'level' => \Dot\Log\Logger::ALERT, // this is equal to 1 + 'name' => 'stream', + 'level' => Logger::ALERT, 'options' => [ - 'stream' => __DIR__ . '/../../log/queue-log.log', + 'stream' => __DIR__ . '/../../log/queue-log.log', 'formatter' => [ 'name' => Json::class, ], ], ], ], - ] + ], ], ], ]; diff --git a/config/autoload/messenger.local.php.dist b/config/autoload/messenger.local.php.dist index 4268d3b..4ccffb6 100644 --- a/config/autoload/messenger.local.php.dist +++ b/config/autoload/messenger.local.php.dist @@ -1,25 +1,28 @@ [ - "messenger" => [ - "transports" => [ - "redis_transport" => [ - 'dsn' => 'redis://127.0.0.1:6379/messages', - 'options' => [], // Redis specific options + 'symfony' => [ + 'messenger' => [ + 'transports' => [ + 'redis_transport' => [ + 'dsn' => 'redis://127.0.0.1:6379/messages', + 'options' => [], // Redis specific options 'serializer' => SymfonySerializer::class, - ] - ] - ] + ], + ], + ], + ], + 'dependencies' => [ + 'factories' => [ + 'redis_transport' => [TransportFactory::class, 'redis_transport'], + SymfonySerializer::class => fn(ContainerInterface $container) => new PhpSerializer(), + ], ], - "dependencies" => [ - "factories" => [ - "redis_transport" => [TransportFactory::class, 'redis_transport'], - SymfonySerializer::class => fn(\Psr\Container\ContainerInterface $container) => new PhpSerializer() - ] - ] -]; \ No newline at end of file +]; diff --git a/config/autoload/swoole.local.php.dist b/config/autoload/swoole.local.php.dist index 84262fe..7085ee0 100644 --- a/config/autoload/swoole.local.php.dist +++ b/config/autoload/swoole.local.php.dist @@ -1,9 +1,10 @@ [ - // Available in Swoole 4.1 and up; enables coroutine support - // for most I/O operations: + // Available in Swoole 4.1 and up; enables coroutine support for most I/O operations: 'enable_coroutine' => true, // Configure Swoole TCP Server: @@ -13,17 +14,17 @@ return [ 'mode' => SWOOLE_BASE, // SWOOLE_BASE or SWOOLE_PROCESS; // SWOOLE_BASE is the default 'protocol' => SWOOLE_SOCK_TCP, // SWOOLE_SSL, // SSL-enable the server - 'options' => [ + 'options' => [ // Set the SSL certificate and key paths for SSL support: //'ssl_cert_file' => 'path/to/ssl.crt', //'ssl_key_file' => 'path/to/ssl.key', - // Whether or not the HTTP server should use coroutines; + // Whether the HTTP server should use coroutines; // enabled by default, and generally should not be disabled: - 'package_eof' => "\n", - 'open_eof_check' => true, + 'package_eof' => PHP_EOL, + 'open_eof_check' => true, 'open_length_check' => true, - // in order to run swoole as daemon + // to run swoole as a daemon 'daemonize' => true, // Overwrite the default location of the pid file; diff --git a/daemon/messenger.service b/daemon/messenger.service index f1dcea0..daa7fb2 100644 --- a/daemon/messenger.service +++ b/daemon/messenger.service @@ -12,4 +12,4 @@ WorkingDirectory=/home/dotkernel/queue/ ExecStart=/usr/bin/php /home/dotkernel/queue/bin/cli.php messenger:start [Install] -WantedBy=swoole.service \ No newline at end of file +WantedBy=swoole.service diff --git a/daemon/swoole.service b/daemon/swoole.service index 21ad0c2..b6d2c90 100644 --- a/daemon/swoole.service +++ b/daemon/swoole.service @@ -12,4 +12,4 @@ WorkingDirectory=/home/dotkernel/queue/ ExecStart=/usr/bin/php /home/dotkernel/queue/bin/cli.php swoole:start [Install] -WantedBy=multi-user.target \ No newline at end of file +WantedBy=multi-user.target diff --git a/phpcs.xml b/phpcs.xml index 1eddf9f..1d560a0 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -13,10 +13,10 @@ config + public src test config/config.php - config/routes.php diff --git a/phpstan.neon b/phpstan.neon index ed056f0..9da6dbc 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -4,6 +4,8 @@ includes: parameters: level: 5 paths: + - config + - public - src - test treatPhpDocTypesAsCertain: false diff --git a/public/index.php b/public/index.php index 1c0c9bc..ee49413 100644 --- a/public/index.php +++ b/public/index.php @@ -2,6 +2,10 @@ declare(strict_types=1); +use Mezzio\Application; +use Mezzio\MiddlewareFactory; +use Psr\Container\ContainerInterface; + // Delegate static file requests back to the PHP built-in webserver if (PHP_SAPI === 'cli-server' && $_SERVER['SCRIPT_FILENAME'] !== __FILE__) { return false; @@ -14,17 +18,15 @@ * Self-called anonymous function that creates its own scope and keeps the global namespace clean. */ (function () { - /** @var \Psr\Container\ContainerInterface $container */ + /** @var ContainerInterface $container */ $container = require 'config/container.php'; - /** @var \Mezzio\Application $app */ - $app = $container->get(\Mezzio\Application::class); - $factory = $container->get(\Mezzio\MiddlewareFactory::class); + /** @var Application $app */ + $app = $container->get(Application::class); + $factory = $container->get(MiddlewareFactory::class); - // Execute programmatic/declarative middleware pipeline and routing - // configuration statements + // Execute programmatic/declarative middleware pipeline and routing configuration statements (require 'config/pipeline.php')($app, $factory, $container); - (require 'config/routes.php')($app, $factory, $container); $app->run(); })(); diff --git a/src/App/ConfigProvider.php b/src/App/ConfigProvider.php index 32641e6..8040eb4 100644 --- a/src/App/ConfigProvider.php +++ b/src/App/ConfigProvider.php @@ -19,7 +19,7 @@ class ConfigProvider public function __invoke(): array { return [ - "dependencies" => $this->getDependencies(), + 'dependencies' => $this->getDependencies(), 'symfony' => [ 'messenger' => [ 'buses' => $this->busConfig(), @@ -31,15 +31,15 @@ public function __invoke(): array private function getDependencies(): array { return [ - "factories" => [ - "message_bus" => [MessageBusStaticFactory::class, "message_bus"], - "message_bus_stamp_middleware" => [BusNameStampMiddlewareStaticFactory::class, "message_bus"], - "message_bus_sender_middleware" => [MessageSenderMiddlewareStaticFactory::class, "message_bus"], - "message_bus_handler_middleware" => [MessageHandlerMiddlewareStaticFactory::class, "message_bus"], + 'factories' => [ + 'message_bus' => [MessageBusStaticFactory::class, 'message_bus'], + 'message_bus_stamp_middleware' => [BusNameStampMiddlewareStaticFactory::class, 'message_bus'], + 'message_bus_sender_middleware' => [MessageSenderMiddlewareStaticFactory::class, 'message_bus'], + 'message_bus_handler_middleware' => [MessageHandlerMiddlewareStaticFactory::class, 'message_bus'], MessageHandler::class => AttributedServiceFactory::class, ], - "aliases" => [ - MessageBusInterface::class => "message_bus", + 'aliases' => [ + MessageBusInterface::class => 'message_bus', ], ]; } @@ -47,7 +47,7 @@ private function getDependencies(): array private function busConfig(): array { return [ - "message_bus" => [ + 'message_bus' => [ // Means that it's an error if no handlers are defined for a given message 'allows_zero_handlers' => false, @@ -58,7 +58,7 @@ private function busConfig(): array */ 'middleware' => [ // … Middleware that inspects the message before it has been sent to a transport would go here. - "message_bus_stamp_middleware", + 'message_bus_stamp_middleware', 'message_bus_sender_middleware', // Sends messages via a transport if configured. 'message_bus_handler_middleware', // Executes the handlers configured for the message ], @@ -78,16 +78,16 @@ private function busConfig(): array * Routes define which transport(s) that messages dispatched on this bus should be sent with. * * The * wildcard applies to all messages. - * The transport for each route must be an array of one or more transport identifiers. Each transport - * is retrieved from the DI container by this value. + * The transport for each route must be an array of one or more transport identifiers. + * This value retrieves each transport from the DI container. * * An empty routes definition would mean that messages would be handled immediately and synchronously, - * i.e. no transport would be used. + * i.e., no transport would be used. * * Route specific messages to specific transports by using the message name as the key. */ 'routes' => [ - Message::class => ["redis_transport"], + Message::class => ['redis_transport'], ], ], ]; diff --git a/src/App/Message/MessageHandler.php b/src/App/Message/MessageHandler.php index 74d008b..36b6e1a 100644 --- a/src/App/Message/MessageHandler.php +++ b/src/App/Message/MessageHandler.php @@ -6,9 +6,11 @@ use Dot\DependencyInjection\Attribute\Inject; use Dot\Log\Logger; +use Exception; use Symfony\Component\Messenger\Exception\ExceptionInterface; use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Messenger\Stamp\DelayStamp; +use Throwable; class MessageHandler { @@ -24,6 +26,9 @@ public function __construct( ) { } + /** + * @throws ExceptionInterface + */ public function __invoke(Message $message): void { $payload = $message->getPayload(); @@ -35,9 +40,9 @@ public function __invoke(Message $message): void if ($payload['foo'] === 'control') { $this->logger->info($payload['foo'] . ': was processed successfully'); } else { - throw new \Exception("Failed to execute"); + throw new Exception('Failed to execute'); } - } catch (\Throwable $exception) { + } catch (Throwable $exception) { $this->logger->error($payload['foo'] . ' failed with message: ' . $exception->getMessage() . ' after ' . ($payload['retry'] ?? 0) . ' retries'); $this->retry($payload); @@ -50,7 +55,7 @@ public function __invoke(Message $message): void public function retry(array $payload): void { if (! isset($payload['retry'])) { - $this->bus->dispatch(new Message(["foo" => $payload['foo'], 'retry' => 1]), [ + $this->bus->dispatch(new Message(['foo' => $payload['foo'], 'retry' => 1]), [ new DelayStamp($this->config['fail-safe']['first_retry']), ]); } else { @@ -58,13 +63,13 @@ public function retry(array $payload): void switch ($retry) { case 1: $delay = $this->config['fail-safe']['second_retry']; - $this->bus->dispatch(new Message(["foo" => $payload['foo'], 'retry' => ++$retry]), [ + $this->bus->dispatch(new Message(['foo' => $payload['foo'], 'retry' => ++$retry]), [ new DelayStamp($delay), ]); break; case 2: $delay = $this->config['fail-safe']['third_retry']; - $this->bus->dispatch(new Message(["foo" => $payload['foo'], 'retry' => ++$retry]), [ + $this->bus->dispatch(new Message(['foo' => $payload['foo'], 'retry' => ++$retry]), [ new DelayStamp($delay), ]); break; diff --git a/src/Swoole/Command/Factory/StopCommandFactory.php b/src/Swoole/Command/Factory/StopCommandFactory.php index d9d3de4..f21ee9f 100644 --- a/src/Swoole/Command/Factory/StopCommandFactory.php +++ b/src/Swoole/Command/Factory/StopCommandFactory.php @@ -4,12 +4,18 @@ namespace Queue\Swoole\Command\Factory; +use Psr\Container\ContainerExceptionInterface; use Psr\Container\ContainerInterface; +use Psr\Container\NotFoundExceptionInterface; use Queue\Swoole\Command\StopCommand; use Queue\Swoole\PidManager; class StopCommandFactory { + /** + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ public function __invoke(ContainerInterface $container): StopCommand { return new StopCommand($container->get(PidManager::class)); diff --git a/src/Swoole/Command/GetFailedMessagesCommand.php b/src/Swoole/Command/GetFailedMessagesCommand.php index 83da758..02c6638 100644 --- a/src/Swoole/Command/GetFailedMessagesCommand.php +++ b/src/Swoole/Command/GetFailedMessagesCommand.php @@ -4,7 +4,10 @@ namespace Queue\Swoole\Command; +use DateTime; +use DateTimeImmutable; use Dot\DependencyInjection\Attribute\Inject; +use Exception; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; @@ -31,7 +34,7 @@ class GetFailedMessagesCommand extends Command /** @var string $defaultName */ protected static $defaultName = 'failed'; - #[Inject()] + #[Inject] public function __construct() { parent::__construct(self::$defaultName); @@ -52,15 +55,15 @@ protected function execute(InputInterface $input, OutputInterface $output): int $endOption = $input->getOption('end'); $limit = $input->getOption('limit'); - $startDate = $startOption ? new \DateTimeImmutable($startOption) : null; - $endDate = $endOption ? new \DateTimeImmutable($endOption) : null; - } catch (\Exception $e) { + $startDate = $startOption ? new DateTimeImmutable($startOption) : null; + $endDate = $endOption ? new DateTimeImmutable($endOption) : null; + } catch (Exception) { $output->writeln('Invalid date format provided.'); return Command::FAILURE; } if ($startDate && $startDate->format('H:i:s') === '00:00:00') { - $startDate = $startDate->setTime(0, 0, 0); + $startDate = $startDate->setTime(0, 0); } if ($endDate && $endDate->format('H:i:s') === '00:00:00') { @@ -69,14 +72,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int if ($limit && is_numeric($limit)) { if ($startDate && ! $endDate) { - $endDate = $startDate->modify("+{$limit} days"); + $endDate = $startDate->modify("+$limit days"); } elseif (! $startDate && $endDate) { - $startDate = $endDate->modify("-{$limit} days"); + $startDate = $endDate->modify("-$limit days"); } } if (! $endDate) { - $endDate = new \DateTime(); + $endDate = new DateTime(); } if ($startDate > $endDate) { @@ -87,7 +90,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $logPath = dirname(__DIR__, 3) . '/log/queue-log.log'; if (! file_exists($logPath)) { - $output->writeln("Log file not found: $logPath"); + $output->writeln("Log file was not found: $logPath"); return Command::FAILURE; } diff --git a/src/Swoole/Command/GetProcessedMessagesCommand.php b/src/Swoole/Command/GetProcessedMessagesCommand.php index 846dfe7..d92ff4b 100644 --- a/src/Swoole/Command/GetProcessedMessagesCommand.php +++ b/src/Swoole/Command/GetProcessedMessagesCommand.php @@ -4,7 +4,10 @@ namespace Queue\Swoole\Command; +use DateTime; +use DateTimeImmutable; use Dot\DependencyInjection\Attribute\Inject; +use Exception; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; @@ -31,7 +34,7 @@ class GetProcessedMessagesCommand extends Command /** @var string $defaultName */ protected static $defaultName = 'processed'; - #[Inject()] + #[Inject] public function __construct() { parent::__construct(self::$defaultName); @@ -52,15 +55,15 @@ protected function execute(InputInterface $input, OutputInterface $output): int $endOption = $input->getOption('end'); $limit = $input->getOption('limit'); - $startDate = $startOption ? new \DateTimeImmutable($startOption) : null; - $endDate = $endOption ? new \DateTimeImmutable($endOption) : null; - } catch (\Exception $e) { + $startDate = $startOption ? new DateTimeImmutable($startOption) : null; + $endDate = $endOption ? new DateTimeImmutable($endOption) : null; + } catch (Exception) { $output->writeln('Invalid date format provided.'); return Command::FAILURE; } if ($startDate && $startDate->format('H:i:s') === '00:00:00') { - $startDate = $startDate->setTime(0, 0, 0); + $startDate = $startDate->setTime(0, 0); } if ($endDate && $endDate->format('H:i:s') === '00:00:00') { @@ -69,14 +72,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int if ($limit && is_numeric($limit)) { if ($startDate && ! $endDate) { - $endDate = $startDate->modify("+{$limit} days"); + $endDate = $startDate->modify("+$limit days"); } elseif (! $startDate && $endDate) { - $startDate = $endDate->modify("-{$limit} days"); + $startDate = $endDate->modify("-$limit days"); } } if (! $endDate) { - $endDate = new \DateTime(); + $endDate = new DateTime(); } if ($startDate > $endDate) { @@ -87,7 +90,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $logPath = dirname(__DIR__, 3) . '/log/queue-log.log'; if (! file_exists($logPath)) { - $output->writeln("Log file not found: $logPath"); + $output->writeln("Log file was not found: $logPath"); return Command::FAILURE; } diff --git a/src/Swoole/Command/IsRunningTrait.php b/src/Swoole/Command/IsRunningTrait.php index 6e7966a..a7ceb02 100644 --- a/src/Swoole/Command/IsRunningTrait.php +++ b/src/Swoole/Command/IsRunningTrait.php @@ -9,7 +9,7 @@ trait IsRunningTrait { /** - * Is the swoole server running? + * Is the Swoole server running? */ public function isRunning(): bool { diff --git a/src/Swoole/Command/StartCommand.php b/src/Swoole/Command/StartCommand.php index 62ac0b2..c1eb1cd 100644 --- a/src/Swoole/Command/StartCommand.php +++ b/src/Swoole/Command/StartCommand.php @@ -4,7 +4,9 @@ namespace Queue\Swoole\Command; +use Psr\Container\ContainerExceptionInterface; use Psr\Container\ContainerInterface; +use Psr\Container\NotFoundExceptionInterface; use Queue\Swoole\PidManager; use Swoole\Server as SwooleServer; use Symfony\Component\Console\Attribute\AsCommand; @@ -24,8 +26,6 @@ class StartCommand extends Command public const DEFAULT_PROCESS_NAME = 'dotkernel-queue'; - public const DEFAULT_NUM_WORKERS = 4; - public const HELP = <<<'EOH' Start the web server. If --daemonize is provided, starts the server as a background process and returns handling to the shell; otherwise, the @@ -35,8 +35,7 @@ class StartCommand extends Command do not provide the option, 4 workers will be started. EOH; - /** @var ContainerInterface */ - private $container; + private ContainerInterface $container; public function __construct(ContainerInterface $container, string $name = 'start') { @@ -51,6 +50,10 @@ protected function configure(): void $this->setHelp(self::HELP); } + /** + * @throws NotFoundExceptionInterface + * @throws ContainerExceptionInterface + */ protected function execute(InputInterface $input, OutputInterface $output): int { $this->pidManager = $this->container->get(PidManager::class); @@ -61,8 +64,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $server = $this->container->get(SwooleServer::class); $config = $this->container->get('config'); - $processName = $config['dotkernel-queue-swoole']['swoole-server']['process-name'] - ?? self::DEFAULT_PROCESS_NAME; + $processName = $config['dotkernel-queue-swoole']['swoole-server']['process-name'] ?? self::DEFAULT_PROCESS_NAME; $pidManager = $this->pidManager; diff --git a/src/Swoole/Command/StopCommand.php b/src/Swoole/Command/StopCommand.php index 614b544..b64d2b3 100644 --- a/src/Swoole/Command/StopCommand.php +++ b/src/Swoole/Command/StopCommand.php @@ -28,22 +28,20 @@ class StopCommand extends Command /** * @internal * - * @var Closure Callable to execute when attempting to kill the server - * process. Generally speaking, this is SwooleProcess::kill; only - * change the value when testing. + * Callable to execute when attempting to kill the server process. + * Generally speaking, this is SwooleProcess::kill; only change the value when testing. */ - public $killProcess; + public Closure $killProcess; /** * @internal * - * @var int How long to wait for the server process to end. Only change - * the value when testing. + * How long to wait for the server process to end. + * Only change the value when testing. */ - public $waitThreshold = 60; + public int $waitThreshold = 60; - /** @var PidManager */ - private $pidManager; + private PidManager $pidManager; public function __construct(PidManager $pidManager, string $name = 'stop') { diff --git a/src/Swoole/ConfigProvider.php b/src/Swoole/ConfigProvider.php index a7976f8..4a30284 100644 --- a/src/Swoole/ConfigProvider.php +++ b/src/Swoole/ConfigProvider.php @@ -27,10 +27,10 @@ public function __invoke(): array public function getDependencies(): array { return [ - "delegators" => [ + 'delegators' => [ TCPSwooleServer::class => [TCPServerDelegator::class], ], - "factories" => [ + 'factories' => [ TCPSwooleServer::class => ServerFactory::class, PidManager::class => PidManagerFactory::class, StartCommand::class => StartCommandFactory::class, @@ -39,7 +39,6 @@ public function getDependencies(): array GetFailedMessagesCommand::class => AttributedServiceFactory::class, GetQueuedMessagesCommand::class => AttributedServiceFactory::class, ], - "aliases" => [], ]; } } diff --git a/src/Swoole/Delegators/TCPServerDelegator.php b/src/Swoole/Delegators/TCPServerDelegator.php index 3b9b67a..5bcbf84 100644 --- a/src/Swoole/Delegators/TCPServerDelegator.php +++ b/src/Swoole/Delegators/TCPServerDelegator.php @@ -4,7 +4,9 @@ namespace Queue\Swoole\Delegators; +use Psr\Container\ContainerExceptionInterface; use Psr\Container\ContainerInterface; +use Psr\Container\NotFoundExceptionInterface; use Queue\App\Message\Message; use Queue\Swoole\Command\GetFailedMessagesCommand; use Queue\Swoole\Command\GetProcessedMessagesCommand; @@ -15,6 +17,7 @@ use Symfony\Component\Console\Output\BufferedOutput; use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Messenger\Stamp\DelayStamp; +use Throwable; use function array_merge; use function array_shift; @@ -23,8 +26,14 @@ use function str_starts_with; use function trim; +use const PHP_EOL; + class TCPServerDelegator { + /** + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ public function __invoke(ContainerInterface $container, string $serviceName, callable $callback): TCPSwooleServer { /** @var TCPSwooleServer $server */ @@ -33,22 +42,20 @@ public function __invoke(ContainerInterface $container, string $serviceName, cal /** @var MessageBusInterface $bus */ $bus = $container->get(MessageBusInterface::class); - $logger = $container->get("dot-log.queue-log"); - - $commandMap = [ - 'processed' => GetProcessedMessagesCommand::class, - 'failed' => GetFailedMessagesCommand::class, - 'inventory' => GetQueuedMessagesCommand::class, - ]; + $logger = $container->get('dot-log.queue-log'); - $server->on('Connect', function ($server, $fd) { - echo "Client: Connect.\n"; + $server->on('connect', function (TCPSwooleServer $server, int $fd) { + echo 'Client: Connect.' . PHP_EOL; }); - $server->on('receive', function ($server, $fd, $fromId, $data) use ($logger, $bus, $commandMap, $container) { - $message = trim($data); - $response = ''; + $server->on('receive', function ($server, $fd, $fromId, $data) use ($logger, $bus, $container) { + $commandMap = [ + 'processed' => GetProcessedMessagesCommand::class, + 'failed' => GetFailedMessagesCommand::class, + 'inventory' => GetQueuedMessagesCommand::class, + ]; + $message = trim($data); $args = explode(' ', $message); $commandName = array_shift($args); @@ -75,16 +82,16 @@ public function __invoke(ContainerInterface $container, string $serviceName, cal $application->run($input, $output); $response = $output->fetch(); $server->send($fd, $response); - } catch (\Throwable $e) { - $logger->error("Error running command: " . $e->getMessage()); + } catch (Throwable $e) { + $logger->error('Error running command: ' . $e->getMessage()); } } else { - $bus->dispatch(new Message(["foo" => $message])); - $bus->dispatch(new Message(["foo" => "with 5 seconds delay"]), [ + $bus->dispatch(new Message(['foo' => $message])); + $bus->dispatch(new Message(['foo' => 'with 5 seconds delay']), [ new DelayStamp(5000), ]); - $logger->notice("TCP request received", [ + $logger->notice('TCP request received', [ 'fd' => $fd, 'from_id' => $fromId, 'data' => $data, @@ -92,8 +99,8 @@ public function __invoke(ContainerInterface $container, string $serviceName, cal } }); - $server->on('Close', function ($server, $fd) { - echo "Client: Close.\n"; + $server->on('close', function (TCPSwooleServer $server, int $fd) { + echo 'Client: Close.' . PHP_EOL; }); return $server; diff --git a/src/Swoole/PidManager.php b/src/Swoole/PidManager.php index b21c1ab..427d529 100644 --- a/src/Swoole/PidManager.php +++ b/src/Swoole/PidManager.php @@ -22,7 +22,7 @@ public function __construct(private string $pidFile) } /** - * Write master pid and manager pid to pid file + * Write master pid and manager pid to a pid file * * @throws RuntimeException When $pidFile is not writable. */ @@ -36,7 +36,7 @@ public function write(int $masterPid, int $managerPid): void } /** - * Read master pid and manager pid from pid file + * Read master pid and manager pid from a pid file * * @return string[] Array with master and manager PID values as strings */ diff --git a/src/Swoole/PidManagerFactory.php b/src/Swoole/PidManagerFactory.php index 9036816..8c06498 100644 --- a/src/Swoole/PidManagerFactory.php +++ b/src/Swoole/PidManagerFactory.php @@ -4,15 +4,22 @@ namespace Queue\Swoole; +use Psr\Container\ContainerExceptionInterface; use Psr\Container\ContainerInterface; +use Psr\Container\NotFoundExceptionInterface; use function sys_get_temp_dir; class PidManagerFactory { + /** + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ public function __invoke(ContainerInterface $container): PidManager { $config = $container->get('config'); + return new PidManager( $config['dotkernel-queue-swoole']['swoole-tcp-server']['options']['pid_file'] ?? sys_get_temp_dir() . '/dotkernel-queue-swoole.pid' diff --git a/src/Swoole/ServerFactory.php b/src/Swoole/ServerFactory.php index 63354c1..5f7a59f 100644 --- a/src/Swoole/ServerFactory.php +++ b/src/Swoole/ServerFactory.php @@ -5,7 +5,10 @@ namespace Queue\Swoole; use ArrayAccess; +use ErrorException; +use Psr\Container\ContainerExceptionInterface; use Psr\Container\ContainerInterface; +use Psr\Container\NotFoundExceptionInterface; use Queue\Swoole\Exception\InvalidArgumentException; use Swoole\Runtime as SwooleRuntime; use Swoole\Server as SwooleServer; @@ -66,10 +69,12 @@ class ServerFactory * @see https://www.swoole.co.uk/docs/modules/swoole-server-methods#swoole_server-__construct * @see https://www.swoole.co.uk/docs/modules/swoole-server/predefined-constants for $mode and $protocol constant * + * @throws ContainerExceptionInterface + * @throws ErrorException * @throws InvalidArgumentException For invalid $port values. * @throws InvalidArgumentException For invalid $mode values. * @throws InvalidArgumentException For invalid $protocol values. - * @throws \ErrorException + * @throws NotFoundExceptionInterface */ public function __invoke(ContainerInterface $container): SwooleServer { diff --git a/test/App/Message/MessageHandlerTest.php b/test/App/Message/MessageHandlerTest.php index 9e50151..82453cf 100644 --- a/test/App/Message/MessageHandlerTest.php +++ b/test/App/Message/MessageHandlerTest.php @@ -16,11 +16,11 @@ use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Messenger\Stamp\DelayStamp; +use const PHP_EOL; + class MessageHandlerTest extends TestCase { private MessageBusInterface|MockObject $bus; - private Logger $logger; - private array $config; private MessageHandler $handler; /** @@ -29,8 +29,9 @@ class MessageHandlerTest extends TestCase */ protected function setUp(): void { - $this->bus = $this->createMock(MessageBusInterface::class); - $this->logger = new Logger([ + $this->bus = $this->createMock(MessageBusInterface::class); + + $logger = new Logger([ 'writers' => [ 'FileWriter' => [ 'name' => 'null', @@ -38,7 +39,7 @@ protected function setUp(): void ], ], ]); - $this->config = [ + $config = [ 'fail-safe' => [ 'first_retry' => 1000, 'second_retry' => 2000, @@ -49,7 +50,7 @@ protected function setUp(): void 'protocol' => 'tcp', 'host' => 'localhost', 'port' => '8556', - 'eof' => "\n", + 'eof' => PHP_EOL, ], ], 'application' => [ @@ -57,11 +58,12 @@ protected function setUp(): void ], ]; - $this->handler = new MessageHandler($this->bus, $this->logger, $this->config); + $this->handler = new MessageHandler($this->bus, $logger, $config); } /** * @throws Exception + * @throws ExceptionInterface */ public function testInvokeSuccessfulProcessing(): void { @@ -76,6 +78,7 @@ public function testInvokeSuccessfulProcessing(): void /** * @throws Exception + * @throws ExceptionInterface */ public function testInvokeFailureTriggersFirstRetry(): void { diff --git a/test/App/Message/MessageTest.php b/test/App/Message/MessageTest.php index bf98557..8c733a6 100644 --- a/test/App/Message/MessageTest.php +++ b/test/App/Message/MessageTest.php @@ -11,7 +11,7 @@ class MessageTest extends TestCase { public function testMessageAccessors(): void { - $admin = new Message(["payload" => "test message payload"]); - $this->assertSame(["payload" => "test message payload"], $admin->getPayload()); + $admin = new Message(['payload' => 'test message payload']); + $this->assertSame(['payload' => 'test message payload'], $admin->getPayload()); } } diff --git a/test/Swoole/Command/GetDataFromLogsCommandTest.php b/test/Swoole/Command/GetDataFromLogsCommandTest.php index 92803d2..14f5e99 100644 --- a/test/Swoole/Command/GetDataFromLogsCommandTest.php +++ b/test/Swoole/Command/GetDataFromLogsCommandTest.php @@ -4,7 +4,9 @@ namespace QueueTest\Swoole\Command; +use DateTime; use DateTimeImmutable; +use Exception; use PHPUnit\Framework\TestCase; use Queue\Swoole\Command\GetFailedMessagesCommand; use Queue\Swoole\Command\GetProcessedMessagesCommand; @@ -25,15 +27,15 @@ class GetDataFromLogsCommandTest extends TestCase { - private string $logDir; private string $logPath; protected function setUp(): void { - $this->logDir = dirname(__DIR__, 3) . '/log'; - $this->logPath = $this->logDir . '/queue-log.log'; - if (! is_dir($this->logDir)) { - mkdir($this->logDir, 0777, true); + $logDir = dirname(__DIR__, 3) . '/log'; + + $this->logPath = $logDir . '/queue-log.log'; + if (! is_dir($logDir)) { + mkdir($logDir, 0777, true); } file_put_contents($this->logPath, ''); } @@ -92,7 +94,7 @@ public function testMissingLogFile(string $commandClass): void $exit = $command->run($input, $output); $this->assertEquals(Command::FAILURE, $exit); - $this->assertStringContainsString('Log file not found', $output->fetch()); + $this->assertStringContainsString('Log file was not found', $output->fetch()); } /** @@ -120,7 +122,7 @@ public function testNoMatchingEntries(string $commandClass): void */ public function testMalformedLogLineIgnored(string $commandClass): void { - file_put_contents($this->logPath, "not-a-json\n"); + file_put_contents($this->logPath, 'not-a-json' . PHP_EOL); $command = new $commandClass(); $input = new ArrayInput([]); @@ -139,7 +141,7 @@ public function testMatchEntryOutput(string $commandClass, string $expectedLevel { $line = json_encode([ 'levelName' => $expectedLevel, - 'timestamp' => (new \DateTime())->format('Y-m-d H:i:s'), + 'timestamp' => (new DateTime())->format('Y-m-d H:i:s'), 'message' => 'Message here', ]); file_put_contents($this->logPath, $line . PHP_EOL); @@ -155,8 +157,8 @@ public function testMatchEntryOutput(string $commandClass, string $expectedLevel } /** + * @throws Exception * @throws ExceptionInterface - * @throws \DateMalformedStringException */ public function testLimitAddsDaysToStartDateOnly(): void { @@ -170,7 +172,7 @@ public function testLimitAddsDaysToStartDateOnly(): void ]); $output = new BufferedOutput(); - $logDate = (new DateTimeImmutable($start))->modify("+{$limit} days")->format('Y-m-d H:i:s'); + $logDate = (new DateTimeImmutable($start))->modify("+$limit days")->format('Y-m-d H:i:s'); file_put_contents($this->logPath, json_encode([ 'levelName' => 'info', diff --git a/test/Swoole/Command/GetQueuedMessagesCommandTest.php b/test/Swoole/Command/GetQueuedMessagesCommandTest.php index a8edf4b..969842a 100644 --- a/test/Swoole/Command/GetQueuedMessagesCommandTest.php +++ b/test/Swoole/Command/GetQueuedMessagesCommandTest.php @@ -30,6 +30,9 @@ protected function setUp(): void $this->redisMock = $this->createMock(Redis::class); } + /** + * @throws ExceptionInterface + */ public function testExecuteWithNoMessages(): void { $this->redisMock @@ -75,7 +78,7 @@ public function testExecuteWithMessages(): void $this->assertEquals(Command::SUCCESS, $exitCode); foreach (array_keys($fakeMessages) as $id) { - $this->assertStringContainsString("Message ID:", $outputText); + $this->assertStringContainsString('Message ID:', $outputText); $this->assertStringContainsString($id, $outputText); } @@ -91,7 +94,7 @@ public function testRedisThrowsException(): void $this->redisMock ->expects($this->once()) ->method('xRange') - ->willThrowException(new RedisException("Redis unavailable")); + ->willThrowException(new RedisException('Redis unavailable')); $command = new GetQueuedMessagesCommand($this->redisMock); $input = new ArrayInput([]); diff --git a/test/Swoole/Command/StopCommandTest.php b/test/Swoole/Command/StopCommandTest.php index dbdcca2..4e0dd12 100644 --- a/test/Swoole/Command/StopCommandTest.php +++ b/test/Swoole/Command/StopCommandTest.php @@ -49,9 +49,7 @@ public function testExecuteWhenServerStopsSuccessfully(): void $command->method('isRunning')->willReturn(true); - $command->killProcess = function (int $pid, ?int $signal = null): bool { - return true; - }; + $command->killProcess = fn (): bool => true; $tester = new CommandTester($command); $exitCode = $tester->execute([]); diff --git a/test/Swoole/Delegators/DummySwooleServer.php b/test/Swoole/Delegators/DummySwooleServer.php index d864bb9..7cd3710 100644 --- a/test/Swoole/Delegators/DummySwooleServer.php +++ b/test/Swoole/Delegators/DummySwooleServer.php @@ -6,13 +6,21 @@ use Swoole\Server; +use const SWOOLE_BASE; +use const SWOOLE_SOCK_TCP; + class DummySwooleServer extends Server { /** @var array */ public array $callbacks = []; - public function __construct() - { + public function __construct( + string $host = '0.0.0.0', + int $port = 0, + int $mode = SWOOLE_BASE, + int $sockType = SWOOLE_SOCK_TCP, + ) { + parent::__construct($host, $port, $mode, $sockType); } /** diff --git a/test/Swoole/Delegators/TCPServerDelegatorTest.php b/test/Swoole/Delegators/TCPServerDelegatorTest.php index dd90db2..15d690e 100644 --- a/test/Swoole/Delegators/TCPServerDelegatorTest.php +++ b/test/Swoole/Delegators/TCPServerDelegatorTest.php @@ -10,12 +10,15 @@ use PHPUnit\Framework\TestCase; use Psr\Container\ContainerExceptionInterface; use Psr\Container\ContainerInterface; +use Psr\Container\NotFoundExceptionInterface; use Queue\App\Message\Message; use Queue\Swoole\Command\GetProcessedMessagesCommand; use Queue\Swoole\Delegators\TCPServerDelegator; use Symfony\Component\Messenger\Envelope; use Symfony\Component\Messenger\MessageBusInterface; +use const PHP_EOL; + class TCPServerDelegatorTest extends TestCase { private Logger $logger; @@ -43,6 +46,10 @@ protected function setUp(): void $this->server = new DummySwooleServer(); } + /** + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ public function testCallbacksAreRegistered(): void { $callback = fn() => $this->server; @@ -56,15 +63,19 @@ public function testCallbacksAreRegistered(): void $result = $delegator($this->container, 'tcp-server', $callback); $this->assertSame($this->server, $result); - $this->assertArrayHasKey('Connect', $this->server->callbacks); + $this->assertArrayHasKey('connect', $this->server->callbacks); $this->assertArrayHasKey('receive', $this->server->callbacks); - $this->assertArrayHasKey('Close', $this->server->callbacks); + $this->assertArrayHasKey('close', $this->server->callbacks); - foreach (['Connect', 'receive', 'Close'] as $event) { + foreach (['connect', 'receive', 'close'] as $event) { $this->assertIsCallable($this->server->callbacks[$event]); } } + /** + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ public function testConnectOutputsExpectedString(): void { $callback = fn() => $this->server; @@ -77,12 +88,16 @@ public function testConnectOutputsExpectedString(): void $delegator = new TCPServerDelegator(); $delegator($this->container, 'tcp-server', $callback); - $this->expectOutputString("Client: Connect.\n"); + $this->expectOutputString('Client: Connect.' . PHP_EOL); - $connectCb = $this->server->callbacks['Connect']; + $connectCb = $this->server->callbacks['connect']; $connectCb($this->server, 1); } + /** + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ public function testCloseOutputsExpectedString(): void { $callback = fn() => $this->server; @@ -95,12 +110,16 @@ public function testCloseOutputsExpectedString(): void $delegator = new TCPServerDelegator(); $delegator($this->container, 'tcp-server', $callback); - $this->expectOutputString("Client: Close.\n"); + $this->expectOutputString('Client: Close.' . PHP_EOL); - $closeCb = $this->server->callbacks['Close']; + $closeCb = $this->server->callbacks['close']; $closeCb($this->server, 1); } + /** + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ public function testReceiveDispatchesMessagesAndLogsWhenUnknownCommand(): void { $callback = fn() => $this->server; @@ -137,6 +156,10 @@ public function testReceiveDispatchesMessagesAndLogsWhenUnknownCommand(): void $receiveCb($this->server, 42, 5, "hello"); } + /** + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ public function testReceiveExecutesKnownCommandSuccessfully(): void { $callback = fn() => $this->server; @@ -182,11 +205,14 @@ public function send($fd, $data, $serverSocket = -1): bool $this->assertStringContainsString('processed output text', $this->server->sentData); } + /** + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ public function testReceiveParsesKnownOptions(): void { $callback = fn() => $this->server; - $sentData = null; $this->server = new class extends DummySwooleServer { public ?string $sentData = null; diff --git a/test/Swoole/Exception/InvalidStaticResourceMiddlewareExceptionTest.php b/test/Swoole/Exception/InvalidStaticResourceMiddlewareExceptionTest.php index 461edda..35cf1f9 100644 --- a/test/Swoole/Exception/InvalidStaticResourceMiddlewareExceptionTest.php +++ b/test/Swoole/Exception/InvalidStaticResourceMiddlewareExceptionTest.php @@ -6,6 +6,7 @@ use PHPUnit\Framework\TestCase; use Queue\Swoole\Exception\InvalidStaticResourceMiddlewareException; +use stdClass; use function get_debug_type; use function sprintf; @@ -14,7 +15,7 @@ class InvalidStaticResourceMiddlewareExceptionTest extends TestCase { public function testForMiddlewareAtPositionReturnsExpectedException(): void { - $middleware = new \stdClass(); + $middleware = new stdClass(); $position = 2; $exception = InvalidStaticResourceMiddlewareException::forMiddlewareAtPosition($middleware, $position); diff --git a/test/Swoole/PidManagerFactoryTest.php b/test/Swoole/PidManagerFactoryTest.php index b5e52db..39f78b4 100644 --- a/test/Swoole/PidManagerFactoryTest.php +++ b/test/Swoole/PidManagerFactoryTest.php @@ -4,17 +4,20 @@ namespace QueueTest\Swoole; -use PHPUnit\Framework\MockObject\Exception; use PHPUnit\Framework\TestCase; +use Psr\Container\ContainerExceptionInterface; use Psr\Container\ContainerInterface; +use Psr\Container\NotFoundExceptionInterface; use Queue\Swoole\PidManagerFactory; +use ReflectionClass; use ReflectionException; final class PidManagerFactoryTest extends TestCase { /** - * @throws Exception + * @throws ContainerExceptionInterface * @throws ReflectionException + * @throws NotFoundExceptionInterface */ public function testCreatesPidManagerWithConfiguredPidFile(): void { @@ -47,7 +50,7 @@ public function testCreatesPidManagerWithConfiguredPidFile(): void */ private function getPrivateProperty(object $object): mixed { - $reflection = new \ReflectionClass($object); + $reflection = new ReflectionClass($object); $property = $reflection->getProperty('pidFile'); return $property->getValue($object); } diff --git a/test/Swoole/ServerFactoryTest.php b/test/Swoole/ServerFactoryTest.php index a1346f5..618c86c 100644 --- a/test/Swoole/ServerFactoryTest.php +++ b/test/Swoole/ServerFactoryTest.php @@ -7,9 +7,10 @@ use ErrorException; use InvalidArgumentException; use PHPUnit\Framework\Attributes\RunInSeparateProcess; -use PHPUnit\Framework\MockObject\Exception; use PHPUnit\Framework\TestCase; +use Psr\Container\ContainerExceptionInterface; use Psr\Container\ContainerInterface; +use Psr\Container\NotFoundExceptionInterface; use Queue\Swoole\ServerFactory; use Swoole\Server; @@ -28,7 +29,9 @@ protected function setUp(): void } /** - * @throws Exception|ErrorException + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + * @throws ErrorException */ #[RunInSeparateProcess] public function testInvokeWithMinimalValidConfig(): void @@ -48,7 +51,8 @@ public function testInvokeWithMinimalValidConfig(): void } /** - * @throws Exception + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface * @throws ErrorException */ #[RunInSeparateProcess] @@ -78,7 +82,8 @@ public function testInvokeWithCustomValidConfig(): void } /** - * @throws Exception + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface * @throws ErrorException */ public function testThrowsOnInvalidPort(): void @@ -101,7 +106,9 @@ public function testThrowsOnInvalidPort(): void } /** - * @throws Exception|ErrorException + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + * @throws ErrorException */ public function testThrowsOnInvalidMode(): void { @@ -123,7 +130,8 @@ public function testThrowsOnInvalidMode(): void } /** - * @throws Exception + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface * @throws ErrorException */ public function testThrowsOnInvalidProtocol(): void From 3efeb95b37b3e9d8b12dbe650fc3cb0e2cf27914 Mon Sep 17 00:00:00 2001 From: alexmerlin Date: Tue, 26 Aug 2025 14:18:58 +0300 Subject: [PATCH 2/2] Release preparations Signed-off-by: alexmerlin --- test/Swoole/Delegators/DummySwooleServer.php | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/test/Swoole/Delegators/DummySwooleServer.php b/test/Swoole/Delegators/DummySwooleServer.php index 7cd3710..d864bb9 100644 --- a/test/Swoole/Delegators/DummySwooleServer.php +++ b/test/Swoole/Delegators/DummySwooleServer.php @@ -6,21 +6,13 @@ use Swoole\Server; -use const SWOOLE_BASE; -use const SWOOLE_SOCK_TCP; - class DummySwooleServer extends Server { /** @var array */ public array $callbacks = []; - public function __construct( - string $host = '0.0.0.0', - int $port = 0, - int $mode = SWOOLE_BASE, - int $sockType = SWOOLE_SOCK_TCP, - ) { - parent::__construct($host, $port, $mode, $sockType); + public function __construct() + { } /**