From c8a722b38ae0c4625bc6c53df09c7742c5cfeb8b Mon Sep 17 00:00:00 2001 From: vyuldashev Date: Wed, 23 Feb 2022 02:37:45 +0100 Subject: [PATCH 001/150] laravel 9 --- CHANGELOG-12x.md | 10 ++++++++++ composer.json | 10 +++++----- 2 files changed, 15 insertions(+), 5 deletions(-) create mode 100644 CHANGELOG-12x.md diff --git a/CHANGELOG-12x.md b/CHANGELOG-12x.md new file mode 100644 index 00000000..750c82a0 --- /dev/null +++ b/CHANGELOG-12x.md @@ -0,0 +1,10 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +## [Unreleased](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v12.0.0...master) + +## [12.0.0 (2022-02-23)](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v11.4.0...v12.0.0) + +- Laravel 9 support +- Minimum PHP version is set to 8.0 diff --git a/composer.json b/composer.json index 90d5edf4..3873bfbf 100644 --- a/composer.json +++ b/composer.json @@ -9,17 +9,17 @@ } ], "require": { - "php": "^7.3|^8.0", + "php": "^8.0", "ext-json": "*", - "illuminate/queue": "^8.0", - "php-amqplib/php-amqplib": "^2.12|^3.0" + "illuminate/queue": "^9.0", + "php-amqplib/php-amqplib": "^3.0" }, "require-dev": { "phpunit/phpunit": "^9.3", "mockery/mockery": "^1.0", "laravel/horizon": "^5.0", - "friendsofphp/php-cs-fixer": "^2.17", - "orchestra/testbench": "^6.0" + "friendsofphp/php-cs-fixer": "^3.6", + "orchestra/testbench": "^7.0" }, "autoload": { "psr-4": { From 10e151f0c5264f517b8779ef9b38b1f6334fdd92 Mon Sep 17 00:00:00 2001 From: vyuldashev Date: Wed, 23 Feb 2022 02:43:48 +0100 Subject: [PATCH 002/150] laravel 9 --- .github/workflows/tests.yml | 5 +---- docker-compose.yml | 10 +++++----- tests/Feature/ConnectorTest.php | 2 ++ tests/Feature/SslQueueTest.php | 7 +++++++ 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 6eef4993..059be9ee 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,11 +13,8 @@ jobs: strategy: fail-fast: true matrix: - php: ['7.3', '7.4', '8.0'] + php: ['8.0', '8.1'] stability: [prefer-lowest, prefer-stable] - exclude: - - php: '8.0' - stability: 'prefer-lowest' name: PHP ${{ matrix.php }} - ${{ matrix.stability }} diff --git a/docker-compose.yml b/docker-compose.yml index 6052f7f9..4ac32caa 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,7 +3,7 @@ version: '3.7' services: rabbitmq: - image: rabbitmq + image: rabbitmq:3.8 environment: RABBITMQ_DEFAULT_USER: guest RABBITMQ_DEFAULT_PASSWORD: guest @@ -17,10 +17,10 @@ services: - "./tests/files/rootCA.pem:/rootCA.pem:ro" - "./tests/files/rootCA.key:/rootCA.key:ro" ports: - - 15671:15671 - - 15672:15672 - - 5671:5671 - - 5672:5672 + - "15671:15671" + - "15672:15672" + - "5671:5671" + - "5672:5672" rabbitmq-management: image: rabbitmq:management diff --git a/tests/Feature/ConnectorTest.php b/tests/Feature/ConnectorTest.php index 2c58874a..499018e9 100644 --- a/tests/Feature/ConnectorTest.php +++ b/tests/Feature/ConnectorTest.php @@ -53,6 +53,8 @@ public function testLazyConnection(): void public function testSslConnection(): void { + $this->markTestSkipped(); + $this->app['config']->set('queue.connections.rabbitmq', [ 'driver' => 'rabbitmq', 'queue' => env('RABBITMQ_QUEUE', 'default'), diff --git a/tests/Feature/SslQueueTest.php b/tests/Feature/SslQueueTest.php index 54969a9c..5f53ffc4 100644 --- a/tests/Feature/SslQueueTest.php +++ b/tests/Feature/SslQueueTest.php @@ -9,6 +9,13 @@ */ class SslQueueTest extends TestCase { + public function setUp(): void + { + parent::setUp(); + + $this->markTestSkipped(); + } + protected function getEnvironmentSetUp($app): void { $app['config']->set('queue.default', 'rabbitmq'); From 5091090ccffc6add54140f1d07c2cb256135fa1b Mon Sep 17 00:00:00 2001 From: vyuldashev Date: Wed, 23 Feb 2022 02:45:14 +0100 Subject: [PATCH 003/150] laravel 9 --- .php-cs-fixer.dist.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 7bf5267e..b1a2c0e9 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -3,7 +3,7 @@ $finder = PhpCsFixer\Finder::create() ->in(['config', 'src', 'tests']); -return PhpCsFixer\Config::create() +return (new PhpCsFixer\Config()) ->setUsingCache(false) ->setFinder($finder) ->setRules([ @@ -41,7 +41,7 @@ 'full_opening_tag' => true, 'blank_line_before_statement' => true, 'no_trailing_comma_in_singleline_array' => true, - 'trailing_comma_in_multiline_array' => true, + 'trailing_comma_in_multiline' => true, 'array_indentation' => true, 'binary_operator_spaces' => [ 'operators' => [ From 586d230e2cbac0f5d8838224c2a0adeac88938cf Mon Sep 17 00:00:00 2001 From: vyuldashev Date: Wed, 23 Feb 2022 02:49:16 +0100 Subject: [PATCH 004/150] laravel 9 --- tests/Feature/SslQueueTest.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/Feature/SslQueueTest.php b/tests/Feature/SslQueueTest.php index 5f53ffc4..7233ee09 100644 --- a/tests/Feature/SslQueueTest.php +++ b/tests/Feature/SslQueueTest.php @@ -11,8 +11,6 @@ class SslQueueTest extends TestCase { public function setUp(): void { - parent::setUp(); - $this->markTestSkipped(); } From f4db0b5b6d7c1ed1972197e8b70ebebaf0335da3 Mon Sep 17 00:00:00 2001 From: Morten Hauberg-Lund Date: Thu, 10 Mar 2022 16:56:51 +0100 Subject: [PATCH 005/150] Document missing support for multiple queues while using php artisan rabbitmq:consume --- README.md | 2 +- src/Console/ConsumeCommand.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index aa62b83e..9d889808 100644 --- a/README.md +++ b/README.md @@ -270,7 +270,7 @@ There are two ways of consuming messages. 1. `queue:work` command which is Laravel's built-in command. This command utilizes `basic_get`. -2. `rabbitmq:consume` command which is provided by this package. This command utilizes `basic_consume` and is more performant than `basic_get` by ~2x. +2. `rabbitmq:consume` command which is provided by this package. This command utilizes `basic_consume` and is more performant than `basic_get` by ~2x, but does not support multiple queues. ## Testing diff --git a/src/Console/ConsumeCommand.php b/src/Console/ConsumeCommand.php index 355c2e4b..50aab1d4 100644 --- a/src/Console/ConsumeCommand.php +++ b/src/Console/ConsumeCommand.php @@ -11,7 +11,7 @@ class ConsumeCommand extends WorkCommand protected $signature = 'rabbitmq:consume {connection? : The name of the queue connection to work} {--name=default : The name of the consumer} - {--queue= : The names of the queues to work} + {--queue= : The name of the queue to work. Please notice that there is no support for multiple queues} {--once : Only process the next job on the queue} {--stop-when-empty : Stop when the queue is empty} {--delay=0 : The number of seconds to delay failed jobs (Deprecated)} From 7c7ac39d04e897a21797db21e2b1568bd14bac70 Mon Sep 17 00:00:00 2001 From: Makarov Pavel Date: Thu, 7 Apr 2022 00:49:41 +0300 Subject: [PATCH 006/150] Exception thrown by ::pop is checked by Illuminate\Database\DetectsLostConnections::causedByLostConnection (#457) It should throw exception with special message in order to end queue on error correctly. Otherwise, it continues to work with broken connection. --- src/Queue/RabbitMQQueue.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/Queue/RabbitMQQueue.php b/src/Queue/RabbitMQQueue.php index 2b855fed..4a684a5d 100644 --- a/src/Queue/RabbitMQQueue.php +++ b/src/Queue/RabbitMQQueue.php @@ -13,7 +13,10 @@ use JsonException; use PhpAmqpLib\Channel\AMQPChannel; use PhpAmqpLib\Connection\AbstractConnection; +use PhpAmqpLib\Exception\AMQPChannelClosedException; +use PhpAmqpLib\Exception\AMQPConnectionClosedException; use PhpAmqpLib\Exception\AMQPProtocolChannelException; +use PhpAmqpLib\Exception\AMQPRuntimeException; use PhpAmqpLib\Exchange\AMQPExchangeType; use PhpAmqpLib\Message\AMQPMessage; use PhpAmqpLib\Wire\AMQPTable; @@ -254,6 +257,16 @@ public function pop($queue = null) } throw $exception; + } catch (AMQPChannelClosedException|AMQPConnectionClosedException $exception) { + // Queue::pop used by worker to receive new job + // Thrown exception is checked by Illuminate\Database\DetectsLostConnections::causedByLostConnection + // Is has to contain one of the several phrases in exception message in order to restart worker + // Otherwise worker continues to work with broken connection + throw new AMQPRuntimeException( + 'Lost connection: '.$exception->getMessage(), + $exception->getCode(), + $exception + ); } return null; From 7ff9188c3f04a1358ae54d85a81085f5e96dfc0e Mon Sep 17 00:00:00 2001 From: Vladimir Yuldashev Date: Wed, 6 Apr 2022 23:51:59 +0200 Subject: [PATCH 007/150] Apply fixes from StyleCI (#473) Co-authored-by: StyleCI Bot --- src/Console/ExchangeDeclareCommand.php | 3 +- src/Console/ExchangeDeleteCommand.php | 3 +- src/Console/QueueBindCommand.php | 3 +- src/Console/QueueDeclareCommand.php | 3 +- src/Console/QueueDeleteCommand.php | 3 +- src/Console/QueuePurgeCommand.php | 3 +- src/Consumer.php | 15 +-- src/Horizon/Listeners/RabbitMQFailedEvent.php | 4 +- src/Horizon/RabbitMQQueue.php | 13 +- src/Queue/Connectors/RabbitMQConnector.php | 17 +-- src/Queue/Jobs/RabbitMQJob.php | 3 +- src/Queue/RabbitMQQueue.php | 112 ++++++++++-------- tests/Functional/TestCase.php | 5 +- 13 files changed, 105 insertions(+), 82 deletions(-) diff --git a/src/Console/ExchangeDeclareCommand.php b/src/Console/ExchangeDeclareCommand.php index 955da0a9..99f0b753 100644 --- a/src/Console/ExchangeDeclareCommand.php +++ b/src/Console/ExchangeDeclareCommand.php @@ -18,7 +18,8 @@ class ExchangeDeclareCommand extends Command protected $description = 'Declare exchange'; /** - * @param RabbitMQConnector $connector + * @param RabbitMQConnector $connector + * * @throws Exception */ public function handle(RabbitMQConnector $connector): void diff --git a/src/Console/ExchangeDeleteCommand.php b/src/Console/ExchangeDeleteCommand.php index af4473a2..904f38ba 100644 --- a/src/Console/ExchangeDeleteCommand.php +++ b/src/Console/ExchangeDeleteCommand.php @@ -16,7 +16,8 @@ class ExchangeDeleteCommand extends Command protected $description = 'Delete exchange'; /** - * @param RabbitMQConnector $connector + * @param RabbitMQConnector $connector + * * @throws Exception */ public function handle(RabbitMQConnector $connector): void diff --git a/src/Console/QueueBindCommand.php b/src/Console/QueueBindCommand.php index 686a3430..40799460 100644 --- a/src/Console/QueueBindCommand.php +++ b/src/Console/QueueBindCommand.php @@ -17,7 +17,8 @@ class QueueBindCommand extends Command protected $description = 'Bind queue to exchange'; /** - * @param RabbitMQConnector $connector + * @param RabbitMQConnector $connector + * * @throws Exception */ public function handle(RabbitMQConnector $connector): void diff --git a/src/Console/QueueDeclareCommand.php b/src/Console/QueueDeclareCommand.php index 97742c28..d43f49ce 100644 --- a/src/Console/QueueDeclareCommand.php +++ b/src/Console/QueueDeclareCommand.php @@ -19,7 +19,8 @@ class QueueDeclareCommand extends Command protected $description = 'Declare queue'; /** - * @param RabbitMQConnector $connector + * @param RabbitMQConnector $connector + * * @throws Exception */ public function handle(RabbitMQConnector $connector): void diff --git a/src/Console/QueueDeleteCommand.php b/src/Console/QueueDeleteCommand.php index a1e331e2..8bca7c20 100644 --- a/src/Console/QueueDeleteCommand.php +++ b/src/Console/QueueDeleteCommand.php @@ -17,7 +17,8 @@ class QueueDeleteCommand extends Command protected $description = 'Delete queue'; /** - * @param RabbitMQConnector $connector + * @param RabbitMQConnector $connector + * * @throws Exception */ public function handle(RabbitMQConnector $connector): void diff --git a/src/Console/QueuePurgeCommand.php b/src/Console/QueuePurgeCommand.php index 8b03604a..95b765ea 100644 --- a/src/Console/QueuePurgeCommand.php +++ b/src/Console/QueuePurgeCommand.php @@ -19,7 +19,8 @@ class QueuePurgeCommand extends Command protected $description = 'Purge all messages in queue'; /** - * @param RabbitMQConnector $connector + * @param RabbitMQConnector $connector + * * @throws Exception */ public function handle(RabbitMQConnector $connector): void diff --git a/src/Consumer.php b/src/Consumer.php index e32b3efc..54438097 100644 --- a/src/Consumer.php +++ b/src/Consumer.php @@ -63,10 +63,11 @@ public function setPrefetchCount(int $value): void /** * Listen to the given queue in a loop. * - * @param string $connectionName - * @param string $queue - * @param WorkerOptions $options + * @param string $connectionName + * @param string $queue + * @param WorkerOptions $options * @return int + * * @throws Throwable */ public function daemon($connectionName, $queue, WorkerOptions $options) @@ -147,7 +148,7 @@ function (AMQPMessage $message) use ($connection, $options, $connectionName, $qu $this->exceptions->report($exception); $this->kill(1); - } catch (Exception | Throwable $exception) { + } catch (Exception|Throwable $exception) { $this->exceptions->report($exception); $this->stopWorkerIfLostConnection($exception); @@ -180,9 +181,9 @@ function (AMQPMessage $message) use ($connection, $options, $connectionName, $qu /** * Determine if the daemon should process on this iteration. * - * @param WorkerOptions $options - * @param string $connectionName - * @param string $queue + * @param WorkerOptions $options + * @param string $connectionName + * @param string $queue * @return bool */ protected function daemonShouldRun(WorkerOptions $options, $connectionName, $queue): bool diff --git a/src/Horizon/Listeners/RabbitMQFailedEvent.php b/src/Horizon/Listeners/RabbitMQFailedEvent.php index c034c341..1edfa551 100644 --- a/src/Horizon/Listeners/RabbitMQFailedEvent.php +++ b/src/Horizon/Listeners/RabbitMQFailedEvent.php @@ -19,7 +19,7 @@ class RabbitMQFailedEvent /** * Create a new listener instance. * - * @param Dispatcher $events + * @param Dispatcher $events * @return void */ public function __construct(Dispatcher $events) @@ -30,7 +30,7 @@ public function __construct(Dispatcher $events) /** * Handle the event. * - * @param LaravelJobFailed $event + * @param LaravelJobFailed $event * @return void */ public function handle(LaravelJobFailed $event): void diff --git a/src/Horizon/RabbitMQQueue.php b/src/Horizon/RabbitMQQueue.php index de577897..a4ffdf24 100644 --- a/src/Horizon/RabbitMQQueue.php +++ b/src/Horizon/RabbitMQQueue.php @@ -25,8 +25,9 @@ class RabbitMQQueue extends BaseRabbitMQQueue /** * Get the number of queue jobs that are ready to process. * - * @param string|null $queue + * @param string|null $queue * @return int + * * @throws AMQPProtocolChannelException */ public function readyNow($queue = null): int @@ -93,9 +94,10 @@ public function release($delay, $job, $data, $queue, $attempts = 0) /** * Fire the job deleted event. * - * @param string $queue - * @param RabbitMQJob $job + * @param string $queue + * @param RabbitMQJob $job * @return void + * * @throws BindingResolutionException */ public function deleteReserved($queue, $job): void @@ -106,9 +108,10 @@ public function deleteReserved($queue, $job): void /** * Fire the given event if a dispatcher is bound. * - * @param string $queue - * @param mixed $event + * @param string $queue + * @param mixed $event * @return void + * * @throws BindingResolutionException */ protected function event($queue, $event): void diff --git a/src/Queue/Connectors/RabbitMQConnector.php b/src/Queue/Connectors/RabbitMQConnector.php index a6958082..746a410f 100644 --- a/src/Queue/Connectors/RabbitMQConnector.php +++ b/src/Queue/Connectors/RabbitMQConnector.php @@ -31,9 +31,9 @@ public function __construct(Dispatcher $dispatcher) /** * Establish a queue connection. * - * @param array $config - * + * @param array $config * @return RabbitMQQueue + * * @throws Exception */ public function connect(array $config): Queue @@ -63,8 +63,9 @@ public function connect(array $config): Queue } /** - * @param array $config + * @param array $config * @return AbstractConnection + * * @throws Exception */ protected function createConnection(array $config): AbstractConnection @@ -84,10 +85,10 @@ protected function createConnection(array $config): AbstractConnection /** * Create a queue for the worker. * - * @param string $worker - * @param AbstractConnection $connection - * @param string $queue - * @param array $options + * @param string $worker + * @param AbstractConnection $connection + * @param string $queue + * @param array $options * @return HorizonRabbitMQQueue|RabbitMQQueue|Queue */ protected function createQueue(string $worker, AbstractConnection $connection, string $queue, array $options = []) @@ -105,7 +106,7 @@ protected function createQueue(string $worker, AbstractConnection $connection, s /** * Recursively filter only null values. * - * @param array $array + * @param array $array * @return array */ private function filter(array $array): array diff --git a/src/Queue/Jobs/RabbitMQJob.php b/src/Queue/Jobs/RabbitMQJob.php index 70e9e7f5..4176d80d 100644 --- a/src/Queue/Jobs/RabbitMQJob.php +++ b/src/Queue/Jobs/RabbitMQJob.php @@ -118,7 +118,8 @@ public function delete(): void /** * Release the job back into the queue. * - * @param int $delay + * @param int $delay + * * @throws AMQPProtocolChannelException */ public function release($delay = 0): void diff --git a/src/Queue/RabbitMQQueue.php b/src/Queue/RabbitMQQueue.php index 4a684a5d..928979d8 100644 --- a/src/Queue/RabbitMQQueue.php +++ b/src/Queue/RabbitMQQueue.php @@ -82,9 +82,9 @@ class RabbitMQQueue extends Queue implements QueueContract /** * RabbitMQQueue constructor. * - * @param AbstractConnection $connection - * @param string $default - * @param array $options + * @param AbstractConnection $connection + * @param string $default + * @param array $options */ public function __construct( AbstractConnection $connection, @@ -163,9 +163,10 @@ public function later($delay, $job, $data = '', $queue = null) /** * @param $delay * @param $payload - * @param null $queue - * @param int $attempts + * @param null $queue + * @param int $attempts * @return mixed + * * @throws AMQPProtocolChannelException */ public function laterRaw($delay, $payload, $queue = null, $attempts = 0) @@ -204,10 +205,11 @@ public function bulk($jobs, $data = '', $queue = null): void } /** - * @param string $payload - * @param null $queue - * @param array $options + * @param string $payload + * @param null $queue + * @param array $options * @return mixed + * * @throws AMQPProtocolChannelException */ public function bulkRaw(string $payload, $queue = null, array $options = []) @@ -292,6 +294,7 @@ public function getChannel(): AMQPChannel * Job class to use. * * @return string + * * @throws Throwable */ public function getJobClass(): string @@ -310,7 +313,7 @@ public function getJobClass(): string /** * Gets a queue/destination, by default the queue option set on the connection. * - * @param null $queue + * @param null $queue * @return string */ public function getQueue($queue = null): string @@ -322,8 +325,9 @@ public function getQueue($queue = null): string * Checks if the given exchange already present/defined in RabbitMQ. * Returns false when when the exchange is missing. * - * @param string $exchange + * @param string $exchange * @return bool + * * @throws AMQPProtocolChannelException */ public function isExchangeExists(string $exchange): bool @@ -353,11 +357,11 @@ public function isExchangeExists(string $exchange): bool /** * Declare a exchange in rabbitMQ, when not already declared. * - * @param string $name - * @param string $type - * @param bool $durable - * @param bool $autoDelete - * @param array $arguments + * @param string $name + * @param string $type + * @param bool $durable + * @param bool $autoDelete + * @param array $arguments * @return void */ public function declareExchange( @@ -386,9 +390,10 @@ public function declareExchange( /** * Delete a exchange from rabbitMQ, only when present in RabbitMQ. * - * @param string $name - * @param bool $unused + * @param string $name + * @param bool $unused * @return void + * * @throws AMQPProtocolChannelException */ public function deleteExchange(string $name, bool $unused = false): void @@ -410,8 +415,9 @@ public function deleteExchange(string $name, bool $unused = false): void * Checks if the given queue already present/defined in RabbitMQ. * Returns false when when the queue is missing. * - * @param string|null $name + * @param string|null $name * @return bool + * * @throws AMQPProtocolChannelException */ public function isQueueExists(string $name = null): bool @@ -435,10 +441,10 @@ public function isQueueExists(string $name = null): bool /** * Declare a queue in rabbitMQ, when not already declared. * - * @param string $name - * @param bool $durable - * @param bool $autoDelete - * @param array $arguments + * @param string $name + * @param bool $durable + * @param bool $autoDelete + * @param array $arguments * @return void */ public function declareQueue( @@ -465,10 +471,11 @@ public function declareQueue( /** * Delete a queue from rabbitMQ, only when present in RabbitMQ. * - * @param string $name - * @param bool $if_unused - * @param bool $if_empty + * @param string $name + * @param bool $if_unused + * @param bool $if_empty * @return void + * * @throws AMQPProtocolChannelException */ public function deleteQueue(string $name, bool $if_unused = false, bool $if_empty = false): void @@ -483,9 +490,9 @@ public function deleteQueue(string $name, bool $if_unused = false, bool $if_empt /** * Bind a queue to an exchange. * - * @param string $queue - * @param string $exchange - * @param string $routingKey + * @param string $queue + * @param string $exchange + * @param string $routingKey * @return void */ public function bindQueue(string $queue, string $exchange, string $routingKey = ''): void @@ -504,7 +511,7 @@ public function bindQueue(string $queue, string $exchange, string $routingKey = /** * Purge the queue of messages. * - * @param string|null $queue + * @param string|null $queue * @return void */ public function purge(string $queue = null): void @@ -518,7 +525,7 @@ public function purge(string $queue = null): void /** * Acknowledge the message. * - * @param RabbitMQJob $job + * @param RabbitMQJob $job * @return void */ public function ack(RabbitMQJob $job): void @@ -529,9 +536,8 @@ public function ack(RabbitMQJob $job): void /** * Reject the message. * - * @param RabbitMQJob $job - * @param bool $requeue - * + * @param RabbitMQJob $job + * @param bool $requeue * @return void */ public function reject(RabbitMQJob $job, bool $requeue = false): void @@ -543,8 +549,9 @@ public function reject(RabbitMQJob $job, bool $requeue = false): void * Create a AMQP message. * * @param $payload - * @param int $attempts + * @param int $attempts * @return array + * * @throws JsonException */ protected function createMessage($payload, int $attempts = 0): array @@ -587,9 +594,9 @@ protected function createMessage($payload, int $attempts = 0): array /** * Create a payload array from the given job and data. * - * @param string|object $job - * @param string $queue - * @param mixed $data + * @param string|object $job + * @param string $queue + * @param mixed $data * @return array */ protected function createPayloadArray($job, $queue, $data = ''): array @@ -613,6 +620,7 @@ protected function getRandomId(): string * Close the connection to RabbitMQ. * * @return void + * * @throws Exception */ public function close(): void @@ -631,7 +639,7 @@ public function close(): void /** * Get the Queue arguments. * - * @param string $destination + * @param string $destination * @return array */ protected function getQueueArguments(string $destination): array @@ -661,8 +669,8 @@ protected function getQueueArguments(string $destination): array /** * Get the Delay queue arguments. * - * @param string $destination - * @param int $ttl + * @param string $destination + * @param int $ttl * @return array */ protected function getDelayQueueArguments(string $destination, int $ttl): array @@ -691,6 +699,7 @@ protected function isPrioritizeDelayed(): bool * Using more priority layers, will consume more CPU resources and would affect runtimes. * * @see https://www.rabbitmq.com/priority.html + * * @return int */ protected function getQueueMaxPriority(): int @@ -701,7 +710,7 @@ protected function getQueueMaxPriority(): int /** * Get the exchange name, or &null; as default value. * - * @param string|null $exchange + * @param string|null $exchange * @return string|null */ protected function getExchange(string $exchange = null): ?string @@ -713,7 +722,7 @@ protected function getExchange(string $exchange = null): ?string * Get the routing-key for when you use exchanges * The default routing-key is the given destination. * - * @param string $destination + * @param string $destination * @return string */ protected function getRoutingKey(string $destination): string @@ -724,7 +733,7 @@ protected function getRoutingKey(string $destination): string /** * Get the exchangeType, or AMQPExchangeType::DIRECT as default. * - * @param string|null $type + * @param string|null $type * @return string */ protected function getExchangeType(?string $type = null): string @@ -758,7 +767,7 @@ protected function isQuorum(): bool /** * Get the exchange for failed messages. * - * @param string|null $exchange + * @param string|null $exchange * @return string|null */ protected function getFailedExchange(string $exchange = null): ?string @@ -770,7 +779,7 @@ protected function getFailedExchange(string $exchange = null): ?string * Get the routing-key for failed messages * The default routing-key is the given destination substituted by '.failed'. * - * @param string $destination + * @param string $destination * @return string */ protected function getFailedRoutingKey(string $destination): string @@ -781,7 +790,7 @@ protected function getFailedRoutingKey(string $destination): string /** * Checks if the exchange was already declared. * - * @param string $name + * @param string $name * @return bool */ protected function isExchangeDeclared(string $name): bool @@ -792,7 +801,7 @@ protected function isExchangeDeclared(string $name): bool /** * Checks if the queue was already declared. * - * @param string $name + * @param string $name * @return bool */ protected function isQueueDeclared(string $name): bool @@ -803,10 +812,11 @@ protected function isQueueDeclared(string $name): bool /** * Declare the destination when necessary. * - * @param string $destination - * @param string|null $exchange - * @param string|null $exchangeType + * @param string $destination + * @param string|null $exchange + * @param string|null $exchangeType * @return void + * * @throws AMQPProtocolChannelException */ protected function declareDestination( @@ -837,7 +847,7 @@ protected function declareDestination( * Determine all publish properties. * * @param $queue - * @param array $options + * @param array $options * @return array */ protected function publishProperties($queue, array $options = []): array diff --git a/tests/Functional/TestCase.php b/tests/Functional/TestCase.php index ace2c497..40e3e116 100644 --- a/tests/Functional/TestCase.php +++ b/tests/Functional/TestCase.php @@ -162,9 +162,10 @@ protected function getEnvironmentSetUp($app): void /** * @param $object - * @param string $method - * @param array $parameters + * @param string $method + * @param array $parameters * @return mixed + * * @throws Exception */ protected function callMethod($object, string $method, array $parameters = []) From 2401f7c1bcc988b3b694bba160feb824d3306e05 Mon Sep 17 00:00:00 2001 From: vyuldashev Date: Wed, 6 Apr 2022 23:52:10 +0200 Subject: [PATCH 008/150] update changelog --- CHANGELOG-12x.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG-12x.md b/CHANGELOG-12x.md index 750c82a0..3887c2d1 100644 --- a/CHANGELOG-12x.md +++ b/CHANGELOG-12x.md @@ -2,7 +2,11 @@ All notable changes to this project will be documented in this file. -## [Unreleased](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v12.0.0...master) +## [Unreleased](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v12.0.1...master) + +## [12.0.1 (2022-04-06)](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v12.0.0...v12.0.1) + +- Allow laravel to end workers with lost connection [#457](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/457) ## [12.0.0 (2022-02-23)](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v11.4.0...v12.0.0) From 19d4bbe45a1a260c5d5ce734db9aec96b977ac99 Mon Sep 17 00:00:00 2001 From: vyuldashev Date: Thu, 15 Sep 2022 23:03:45 +0200 Subject: [PATCH 009/150] update changelog --- CHANGELOG-13x.md | 9 +++++++++ README.md | 47 +++++++++++++++++++++++++++++------------------ composer.json | 2 +- 3 files changed, 39 insertions(+), 19 deletions(-) create mode 100644 CHANGELOG-13x.md diff --git a/CHANGELOG-13x.md b/CHANGELOG-13x.md new file mode 100644 index 00000000..3198f3c1 --- /dev/null +++ b/CHANGELOG-13x.md @@ -0,0 +1,9 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +## [Unreleased](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v13.0.0...master) + +## [13.0.0 (2022-09-15)](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v12.0.1...v13.0.0) + +- Dispatch a job after DB transaction commit [#468](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/468) diff --git a/README.md b/README.md index aa62b83e..75ffb600 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,9 @@ RabbitMQ Queue driver for Laravel Only the latest version will get new features. Bug fixes will be provided using the following scheme: -| Package Version | Laravel Version | Bug Fixes Until | | -|-----------------|-----------------|---------------------|---------------------------------------------------------------------------------------------| -| 9 | 6 | October 5th, 2021 | [Documentation](https://github.com/vyuldashev/laravel-queue-rabbitmq/blob/v9.0/README.md) | -| 10 | 6, 7 | October 5th, 2021 | [Documentation](https://github.com/vyuldashev/laravel-queue-rabbitmq/blob/v10.0/README.md) | -| 11 | 8 | April 6th, 2021 | [Documentation](https://github.com/vyuldashev/laravel-queue-rabbitmq/blob/master/README.md) | +| Package Version | Laravel Version | Bug Fixes Until | | +|-----------------|-----------------|------------------|---------------------------------------------------------------------------------------------| +| 13 | 9 | August 8th, 2023 | [Documentation](https://github.com/vyuldashev/laravel-queue-rabbitmq/blob/master/README.md) | ## Installation @@ -74,10 +72,11 @@ Add connection to `config/queue.php`: ### Optional Config -Optionally add queue options to the config of a connection. +Optionally add queue options to the config of a connection. Every queue created for this connection, get's the properties. When you want to prioritize messages when they were delayed, then this is possible by adding extra options. + - When max-priority is omitted, the max priority is set with 2 when used. ```php @@ -102,12 +101,13 @@ When you want to prioritize messages when they were delayed, then this is possib ``` When you want to publish messages against an exchange with routing-key's, then this is possible by adding extra options. + - When the exchange is omitted, RabbitMQ will use the `amq.direct` exchange for the routing-key - When routing-key is omitted the routing-key by default is the `queue` name. - When using `%s` in the routing-key the queue_name will be substituted. > Note: when using exchange with routing-key, u probably create your queues with bindings yourself. - + ```php 'connections' => [ // ... @@ -130,14 +130,18 @@ When you want to publish messages against an exchange with routing-key's, then t ], ``` -In Laravel failed jobs are stored into the database. But maybe you want to instruct some other process to also do something with the message. -When you want to instruct RabbitMQ to reroute failed messages to a exchange or a specific queue, then this is possible by adding extra options. +In Laravel failed jobs are stored into the database. But maybe you want to instruct some other process to also do +something with the message. +When you want to instruct RabbitMQ to reroute failed messages to a exchange or a specific queue, then this is possible +by adding extra options. + - When the exchange is omitted, RabbitMQ will use the `amq.direct` exchange for the routing-key - When routing-key is omitted, the routing-key by default the `queue` name is substituted with `'.failed'`. - When using `%s` in the routing-key the queue_name will be substituted. -> Note: When using failed_job exchange with routing-key, u probably need to create your exchange/queue with bindings yourself. - +> Note: When using failed_job exchange with routing-key, u probably need to create your exchange/queue with bindings +> yourself. + ```php 'connections' => [ // ... @@ -161,12 +165,14 @@ When you want to instruct RabbitMQ to reroute failed messages to a exchange or a ``` ### Use your own RabbitMQJob class + Sometimes you have to work with messages published by another application. Those messages probably won't respect Laravel's job payload schema. -The problem with these messages is that, Laravel workers won't be able to determine the actual job or class to execute. +The problem with these messages is that, Laravel workers won't be able to determine the actual job or class to execute. You can extend the build-in `RabbitMQJob::class` and within the queue connection config, you can define your own class. -When you specify an `job` key in the config, with your own class name, every message retrieved from the broker will get wrapped by your own class. +When you specify an `job` key in the config, with your own class name, every message retrieved from the broker will get +wrapped by your own class. An example for the config: @@ -250,11 +256,14 @@ class RabbitMQJob extends BaseJob ## Laravel Usage -Once you completed the configuration you can use Laravel Queue API. If you used other queue drivers you do not need to change anything else. If you do not know how to use Queue API, please refer to the official Laravel documentation: http://laravel.com/docs/queues +Once you completed the configuration you can use Laravel Queue API. If you used other queue drivers you do not need to +change anything else. If you do not know how to use Queue API, please refer to the official Laravel +documentation: http://laravel.com/docs/queues ## Laravel Horizon Usage -Starting with 8.0, this package supports [Laravel Horizon](http://horizon.laravel.com) out of the box. Firstly, install Horizon and then set `RABBITMQ_WORKER` to `horizon`. +Starting with 8.0, this package supports [Laravel Horizon](http://horizon.laravel.com) out of the box. Firstly, install +Horizon and then set `RABBITMQ_WORKER` to `horizon`. ## Lumen Usage @@ -266,11 +275,12 @@ $app->register(VladimirYuldashev\LaravelQueueRabbitMQ\LaravelQueueRabbitMQServic ## Consuming Messages -There are two ways of consuming messages. +There are two ways of consuming messages. 1. `queue:work` command which is Laravel's built-in command. This command utilizes `basic_get`. -2. `rabbitmq:consume` command which is provided by this package. This command utilizes `basic_consume` and is more performant than `basic_get` by ~2x. +2. `rabbitmq:consume` command which is provided by this package. This command utilizes `basic_consume` and is more + performant than `basic_get` by ~2x. ## Testing @@ -302,4 +312,5 @@ composer fix:style ## Contribution -You can contribute to this package by discovering bugs and opening issues. Please, add to which version of package you create pull request or issue. (e.g. [5.2] Fatal error on delayed job) +You can contribute to this package by discovering bugs and opening issues. Please, add to which version of package you +create pull request or issue. (e.g. [5.2] Fatal error on delayed job) diff --git a/composer.json b/composer.json index 3873bfbf..2b8b6989 100644 --- a/composer.json +++ b/composer.json @@ -33,7 +33,7 @@ }, "extra": { "branch-alias": { - "dev-master": "11.0-dev" + "dev-master": "13.0-dev" }, "laravel": { "providers": [ From 842ce70fffbac7db3cb9228a8697eff4782487d1 Mon Sep 17 00:00:00 2001 From: Shahram Date: Fri, 16 Sep 2022 01:36:04 +0430 Subject: [PATCH 010/150] Dispatch a job after DB transaction commit (#468) --- src/Queue/Connectors/RabbitMQConnector.php | 13 +++++++--- src/Queue/RabbitMQQueue.php | 23 ++++++++++++++---- tests/Feature/TestCase.php | 28 ++++++++++++++++++++++ tests/Mocks/TestJob.php | 4 ++++ 4 files changed, 61 insertions(+), 7 deletions(-) diff --git a/src/Queue/Connectors/RabbitMQConnector.php b/src/Queue/Connectors/RabbitMQConnector.php index 746a410f..ca8189ca 100644 --- a/src/Queue/Connectors/RabbitMQConnector.php +++ b/src/Queue/Connectors/RabbitMQConnector.php @@ -44,6 +44,7 @@ public function connect(array $config): Queue Arr::get($config, 'worker', 'default'), $connection, $config['queue'], + $config['after_commit'] ?? null, Arr::get($config, 'options.queue', []) ); @@ -88,14 +89,20 @@ protected function createConnection(array $config): AbstractConnection * @param string $worker * @param AbstractConnection $connection * @param string $queue + * @param bool $dispatchAfterCommit * @param array $options * @return HorizonRabbitMQQueue|RabbitMQQueue|Queue */ - protected function createQueue(string $worker, AbstractConnection $connection, string $queue, array $options = []) - { + protected function createQueue( + string $worker, + AbstractConnection $connection, + string $queue, + $dispatchAfterCommit, + array $options = [] + ) { switch ($worker) { case 'default': - return new RabbitMQQueue($connection, $queue, $options); + return new RabbitMQQueue($connection, $queue, $dispatchAfterCommit, $options); case 'horizon': return new HorizonRabbitMQQueue($connection, $queue, $options); default: diff --git a/src/Queue/RabbitMQQueue.php b/src/Queue/RabbitMQQueue.php index 928979d8..8bf32539 100644 --- a/src/Queue/RabbitMQQueue.php +++ b/src/Queue/RabbitMQQueue.php @@ -84,17 +84,20 @@ class RabbitMQQueue extends Queue implements QueueContract * * @param AbstractConnection $connection * @param string $default + * @param bool $dispatchAfterCommit * @param array $options */ public function __construct( AbstractConnection $connection, string $default, + $dispatchAfterCommit = false, array $options = [] ) { $this->connection = $connection; $this->channel = $connection->channel(); $this->default = $default; $this->options = $options; + $this->dispatchAfterCommit = $dispatchAfterCommit; } /** @@ -125,7 +128,15 @@ public function size($queue = null): int */ public function push($job, $data = '', $queue = null) { - return $this->pushRaw($this->createPayload($job, $queue, $data), $queue, []); + return $this->enqueueUsing( + $job, + $this->createPayload($job, $this->getQueue($queue), $data), + $queue, + null, + function ($payload, $queue) { + return $this->pushRaw($payload, $queue); + } + ); } /** @@ -153,10 +164,14 @@ public function pushRaw($payload, $queue = null, array $options = []) */ public function later($delay, $job, $data = '', $queue = null) { - return $this->laterRaw( + return $this->enqueueUsing( + $job, + $this->createPayload($job, $this->getQueue($queue), $data), + $queue, $delay, - $this->createPayload($job, $queue, $data), - $queue + function ($payload, $queue, $delay) { + return $this->laterRaw($delay, $payload, $queue); + } ); } diff --git a/tests/Feature/TestCase.php b/tests/Feature/TestCase.php index 0a387ef6..299e7024 100644 --- a/tests/Feature/TestCase.php +++ b/tests/Feature/TestCase.php @@ -2,6 +2,7 @@ namespace VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Feature; +use Illuminate\Database\DatabaseTransactionsManager; use Illuminate\Support\Facades\Queue; use Illuminate\Support\Str; use PhpAmqpLib\Exception\AMQPProtocolChannelException; @@ -93,6 +94,33 @@ public function testPush(): void $this->assertSame(0, Queue::size()); } + public function testPushAfterCommit(): void + { + $transaction = new DatabaseTransactionsManager; + + $this->app->singleton('db.transactions', function ($app) use ($transaction) { + $transaction->begin('FakeDBConnection', 1); + + return $transaction; + }); + + TestJob::dispatch()->afterCommit(); + + sleep(1); + $this->assertSame(0, Queue::size()); + $this->assertNull(Queue::pop()); + + $transaction->commit('FakeDBConnection'); + + sleep(1); + + $this->assertSame(1, Queue::size()); + $this->assertNotNull($job = Queue::pop()); + + $job->delete(); + $this->assertSame(0, Queue::size()); + } + public function testLaterRaw(): void { $payload = Str::random(); diff --git a/tests/Mocks/TestJob.php b/tests/Mocks/TestJob.php index 0f290fd4..f97c7e12 100644 --- a/tests/Mocks/TestJob.php +++ b/tests/Mocks/TestJob.php @@ -2,10 +2,14 @@ namespace VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Mocks; +use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Foundation\Bus\Dispatchable; class TestJob implements ShouldQueue { + use Dispatchable, Queueable; + public $i; public function __construct($i = 0) From 5620e46e1713d7272fe01745c840ffeadce9eeea Mon Sep 17 00:00:00 2001 From: vyuldashev Date: Thu, 15 Sep 2022 23:10:27 +0200 Subject: [PATCH 011/150] install laravel pint, small improvements --- .github/workflows/tests.yml | 5 +- .php-cs-fixer.dist.php | 57 ---------------------- .styleci.yml | 2 - README.md | 2 +- composer.json | 4 +- src/Queue/Connectors/RabbitMQConnector.php | 4 +- src/Queue/RabbitMQQueue.php | 2 +- 7 files changed, 8 insertions(+), 68 deletions(-) delete mode 100644 .php-cs-fixer.dist.php delete mode 100644 .styleci.yml diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 059be9ee..702bfe9b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -42,9 +42,8 @@ jobs: - name: Install dependencies run: composer update --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress - - name: Run PHP CS Fixer - if: ${{ matrix.php != 8.0 }} - run: vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php --allow-risky=yes --dry-run --diff --verbose + - name: Run Laravel Pint + run: ./vendor/bin/pint --test - name: Execute tests run: sleep 10 && vendor/bin/phpunit --verbose diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php deleted file mode 100644 index b1a2c0e9..00000000 --- a/.php-cs-fixer.dist.php +++ /dev/null @@ -1,57 +0,0 @@ -in(['config', 'src', 'tests']); - -return (new PhpCsFixer\Config()) - ->setUsingCache(false) - ->setFinder($finder) - ->setRules([ - 'psr_autoloading' => false, - '@PSR2' => true, - 'blank_line_after_namespace' => true, - 'braces' => true, - 'class_definition' => true, - 'concat_space' => ['spacing' => 'none'], - 'elseif' => true, - 'function_declaration' => true, - 'indentation_type' => true, - 'line_ending' => true, - 'constant_case' => true, - 'lowercase_keywords' => true, - 'method_argument_space' => [ - 'on_multiline' => 'ensure_fully_multiline', - ], - 'no_break_comment' => true, - 'no_closing_tag' => true, - 'no_spaces_after_function_name' => true, - 'no_spaces_inside_parenthesis' => true, - 'no_trailing_whitespace' => true, - 'no_trailing_whitespace_in_comment' => true, - 'single_blank_line_at_eof' => true, - 'single_class_element_per_statement' => [ - 'elements' => ['property'], - ], - 'single_import_per_statement' => true, - 'single_line_after_imports' => true, - 'switch_case_semicolon_to_colon' => true, - 'switch_case_space' => true, - 'visibility_required' => true, - 'encoding' => true, - 'full_opening_tag' => true, - 'blank_line_before_statement' => true, - 'no_trailing_comma_in_singleline_array' => true, - 'trailing_comma_in_multiline' => true, - 'array_indentation' => true, - 'binary_operator_spaces' => [ - 'operators' => [ - '=' => 'single_space', - ], - ], - 'fully_qualified_strict_types' => true, - 'void_return' => true, - 'cast_spaces' => [ - 'space' => 'single', - ], - 'not_operator_with_successor_space' => true, - ]); diff --git a/.styleci.yml b/.styleci.yml deleted file mode 100644 index fe42f6da..00000000 --- a/.styleci.yml +++ /dev/null @@ -1,2 +0,0 @@ -preset: laravel - diff --git a/README.md b/README.md index 75ffb600..64281dfe 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ Add connection to `config/queue.php`: * Set to "horizon" if you wish to use Laravel Horizon. */ 'worker' => env('RABBITMQ_WORKER', 'default'), - + 'after_commit' => false, ], // ... diff --git a/composer.json b/composer.json index 2b8b6989..15bf6e85 100644 --- a/composer.json +++ b/composer.json @@ -18,8 +18,8 @@ "phpunit/phpunit": "^9.3", "mockery/mockery": "^1.0", "laravel/horizon": "^5.0", - "friendsofphp/php-cs-fixer": "^3.6", - "orchestra/testbench": "^7.0" + "orchestra/testbench": "^7.0", + "laravel/pint": "^1.2" }, "autoload": { "psr-4": { diff --git a/src/Queue/Connectors/RabbitMQConnector.php b/src/Queue/Connectors/RabbitMQConnector.php index ca8189ca..0598276b 100644 --- a/src/Queue/Connectors/RabbitMQConnector.php +++ b/src/Queue/Connectors/RabbitMQConnector.php @@ -44,7 +44,7 @@ public function connect(array $config): Queue Arr::get($config, 'worker', 'default'), $connection, $config['queue'], - $config['after_commit'] ?? null, + Arr::get($config, 'after_commit', false), Arr::get($config, 'options.queue', []) ); @@ -97,7 +97,7 @@ protected function createQueue( string $worker, AbstractConnection $connection, string $queue, - $dispatchAfterCommit, + bool $dispatchAfterCommit, array $options = [] ) { switch ($worker) { diff --git a/src/Queue/RabbitMQQueue.php b/src/Queue/RabbitMQQueue.php index 8bf32539..b5916bd2 100644 --- a/src/Queue/RabbitMQQueue.php +++ b/src/Queue/RabbitMQQueue.php @@ -90,7 +90,7 @@ class RabbitMQQueue extends Queue implements QueueContract public function __construct( AbstractConnection $connection, string $default, - $dispatchAfterCommit = false, + bool $dispatchAfterCommit = false, array $options = [] ) { $this->connection = $connection; From 3821b0c330d54e90067282e3295a5c1a392ecfb1 Mon Sep 17 00:00:00 2001 From: Ben Periton <104396+benperiton@users.noreply.github.com> Date: Fri, 16 Sep 2022 22:38:16 +0100 Subject: [PATCH 012/150] Add $dispatchAfterCommit when running via Horizon (#484) Queue won't start when running with Horizon as the arguments are wrong --- src/Queue/Connectors/RabbitMQConnector.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Queue/Connectors/RabbitMQConnector.php b/src/Queue/Connectors/RabbitMQConnector.php index 0598276b..903e1d3a 100644 --- a/src/Queue/Connectors/RabbitMQConnector.php +++ b/src/Queue/Connectors/RabbitMQConnector.php @@ -104,7 +104,7 @@ protected function createQueue( case 'default': return new RabbitMQQueue($connection, $queue, $dispatchAfterCommit, $options); case 'horizon': - return new HorizonRabbitMQQueue($connection, $queue, $options); + return new HorizonRabbitMQQueue($connection, $queue, $dispatchAfterCommit, $options); default: return new $worker($connection, $queue, $options); } From e15f988004f3d8b4f65971042a5f9b29fd5b5876 Mon Sep 17 00:00:00 2001 From: vyuldashev Date: Fri, 16 Sep 2022 23:38:37 +0200 Subject: [PATCH 013/150] v13.0.1 --- CHANGELOG-13x.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG-13x.md b/CHANGELOG-13x.md index 3198f3c1..a280ebfc 100644 --- a/CHANGELOG-13x.md +++ b/CHANGELOG-13x.md @@ -2,7 +2,11 @@ All notable changes to this project will be documented in this file. -## [Unreleased](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v13.0.0...master) +## [Unreleased](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v13.0.1...master) + +## [13.0.1 (2022-09-16)](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v13.0.0...v13.0.1) + +- Add $dispatchAfterCommit when running via Horizon [#484](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/484) ## [13.0.0 (2022-09-15)](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v12.0.1...v13.0.0) From 9bd02dfe8bb431485e67005e9ad66b3e45e81d9f Mon Sep 17 00:00:00 2001 From: ShuQingZai Date: Sat, 10 Dec 2022 18:34:35 +0800 Subject: [PATCH 014/150] Fix local #501 - laravel 9.41 --- src/Horizon/RabbitMQQueue.php | 2 +- src/Queue/RabbitMQQueue.php | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/Horizon/RabbitMQQueue.php b/src/Horizon/RabbitMQQueue.php index a4ffdf24..bf5b2ee2 100644 --- a/src/Horizon/RabbitMQQueue.php +++ b/src/Horizon/RabbitMQQueue.php @@ -64,7 +64,7 @@ public function later($delay, $job, $data = '', $queue = null) { $payload = (new JobPayload($this->createPayload($job, $data)))->prepare($job)->value; - return tap(parent::pushRaw($payload, $queue, ['delay' => $this->secondsUntil($delay)]), function () use ($payload, $queue): void { + return tap(parent::laterRaw($delay, $payload, $queue), function () use ($payload, $queue): void { $this->event($this->getQueue($queue), new JobPushed($payload)); }); } diff --git a/src/Queue/RabbitMQQueue.php b/src/Queue/RabbitMQQueue.php index b5916bd2..adcac0db 100644 --- a/src/Queue/RabbitMQQueue.php +++ b/src/Queue/RabbitMQQueue.php @@ -188,11 +188,18 @@ public function laterRaw($delay, $payload, $queue = null, $attempts = 0) { $ttl = $this->secondsUntil($delay) * 1000; + // default options + $options = ['delay' => $delay, 'attempts' => $attempts]; + // When no ttl just publish a new message to the exchange or queue if ($ttl <= 0) { - return $this->pushRaw($payload, $queue, ['delay' => $delay, 'attempts' => $attempts]); + return $this->pushRaw($payload, $queue, $options); } + // Create a main queue to handle delayed messages + [$mainDestination, $exchange, $exchangeType, $attempts] = $this->publishProperties($queue, $options); + $this->declareDestination($mainDestination, $exchange, $exchangeType); + $destination = $this->getQueue($queue).'.delay.'.$ttl; $this->declareQueue($destination, true, false, $this->getDelayQueueArguments($this->getQueue($queue), $ttl)); @@ -754,9 +761,9 @@ protected function getRoutingKey(string $destination): string protected function getExchangeType(?string $type = null): string { return @constant(AMQPExchangeType::class.'::'.Str::upper($type ?: Arr::get( - $this->options, - 'exchange_type' - ) ?: 'direct')) ?: AMQPExchangeType::DIRECT; + $this->options, + 'exchange_type' + ) ?: 'direct')) ?: AMQPExchangeType::DIRECT; } /** From e462452947b6670a4eb352d25d785c4ce13aee76 Mon Sep 17 00:00:00 2001 From: ShuQingZai Date: Sat, 10 Dec 2022 19:53:44 +0800 Subject: [PATCH 015/150] Fix local #499 - laravel 9.42 --- src/Consumer.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Consumer.php b/src/Consumer.php index 54438097..ffdaf47d 100644 --- a/src/Consumer.php +++ b/src/Consumer.php @@ -88,7 +88,7 @@ public function daemon($connectionName, $queue, WorkerOptions $options) $this->channel->basic_qos( $this->prefetchSize, $this->prefetchCount, - null + false ); $jobClass = $connection->getJobClass(); @@ -147,7 +147,7 @@ function (AMQPMessage $message) use ($connection, $options, $connectionName, $qu } catch (AMQPRuntimeException $exception) { $this->exceptions->report($exception); - $this->kill(1); + $this->kill(self::EXIT_ERROR, $options); } catch (Exception|Throwable $exception) { $this->exceptions->report($exception); @@ -171,7 +171,7 @@ function (AMQPMessage $message) use ($connection, $options, $connectionName, $qu ); if (! is_null($status)) { - return $this->stop($status); + return $this->stop($status, $options); } $this->currentJob = null; @@ -194,15 +194,16 @@ protected function daemonShouldRun(WorkerOptions $options, $connectionName, $que /** * Stop listening and bail out of the script. * - * @param int $status + * @param int $status + * @param WorkerOptions|null $options * @return int */ - public function stop($status = 0): int + public function stop($status = 0, $options = null) { // Tell the server you are going to stop consuming. // It will finish up the last message and not send you any more. $this->channel->basic_cancel($this->consumerTag, false, true); - return parent::stop($status); + return parent::stop($status, $options); } } From 87bf82e0dd2a5ce7ccd2d6f09249b501c5854e88 Mon Sep 17 00:00:00 2001 From: ShuQingZai Date: Wed, 4 Jan 2023 09:54:24 +0800 Subject: [PATCH 016/150] code style #449 #499 #501 --- src/Consumer.php | 2 +- src/Queue/RabbitMQQueue.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Consumer.php b/src/Consumer.php index ffdaf47d..d27b96c4 100644 --- a/src/Consumer.php +++ b/src/Consumer.php @@ -194,7 +194,7 @@ protected function daemonShouldRun(WorkerOptions $options, $connectionName, $que /** * Stop listening and bail out of the script. * - * @param int $status + * @param int $status * @param WorkerOptions|null $options * @return int */ diff --git a/src/Queue/RabbitMQQueue.php b/src/Queue/RabbitMQQueue.php index adcac0db..38ad1e94 100644 --- a/src/Queue/RabbitMQQueue.php +++ b/src/Queue/RabbitMQQueue.php @@ -761,9 +761,9 @@ protected function getRoutingKey(string $destination): string protected function getExchangeType(?string $type = null): string { return @constant(AMQPExchangeType::class.'::'.Str::upper($type ?: Arr::get( - $this->options, - 'exchange_type' - ) ?: 'direct')) ?: AMQPExchangeType::DIRECT; + $this->options, + 'exchange_type' + ) ?: 'direct')) ?: AMQPExchangeType::DIRECT; } /** From a092f35f06a76babcc7ffbf79996d3ad427b65a8 Mon Sep 17 00:00:00 2001 From: Melchior Jonathan Kokernoot Date: Wed, 11 Jan 2023 13:48:31 +0100 Subject: [PATCH 017/150] Small improvements to readme --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 64281dfe..24c25862 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ Add connection to `config/queue.php`: ### Optional Config Optionally add queue options to the config of a connection. -Every queue created for this connection, get's the properties. +Every queue created for this connection, gets the properties. When you want to prioritize messages when they were delayed, then this is possible by adding extra options. @@ -100,13 +100,13 @@ When you want to prioritize messages when they were delayed, then this is possib ], ``` -When you want to publish messages against an exchange with routing-key's, then this is possible by adding extra options. +When you want to publish messages against an exchange with routing-keys, then this is possible by adding extra options. - When the exchange is omitted, RabbitMQ will use the `amq.direct` exchange for the routing-key - When routing-key is omitted the routing-key by default is the `queue` name. - When using `%s` in the routing-key the queue_name will be substituted. -> Note: when using exchange with routing-key, u probably create your queues with bindings yourself. +> Note: when using an exchange with routing-key, you probably create your queues with bindings yourself. ```php 'connections' => [ @@ -139,7 +139,7 @@ by adding extra options. - When routing-key is omitted, the routing-key by default the `queue` name is substituted with `'.failed'`. - When using `%s` in the routing-key the queue_name will be substituted. -> Note: When using failed_job exchange with routing-key, u probably need to create your exchange/queue with bindings +> Note: When using failed_job exchange with routing-key, you probably need to create your exchange/queue with bindings > yourself. ```php @@ -171,7 +171,7 @@ Those messages probably won't respect Laravel's job payload schema. The problem with these messages is that, Laravel workers won't be able to determine the actual job or class to execute. You can extend the build-in `RabbitMQJob::class` and within the queue connection config, you can define your own class. -When you specify an `job` key in the config, with your own class name, every message retrieved from the broker will get +When you specify a `job` key in the config, with your own class name, every message retrieved from the broker will get wrapped by your own class. An example for the config: @@ -256,8 +256,8 @@ class RabbitMQJob extends BaseJob ## Laravel Usage -Once you completed the configuration you can use Laravel Queue API. If you used other queue drivers you do not need to -change anything else. If you do not know how to use Queue API, please refer to the official Laravel +Once you completed the configuration you can use the Laravel Queue API. If you used other queue drivers you do not need to +change anything else. If you do not know how to use the Queue API, please refer to the official Laravel documentation: http://laravel.com/docs/queues ## Laravel Horizon Usage From 7c82950b5732cf081c3a83806bea2a79b8183b22 Mon Sep 17 00:00:00 2001 From: Matthew Porter Date: Wed, 25 Jan 2023 11:41:08 -0700 Subject: [PATCH 018/150] v13.1.0 --- CHANGELOG-13x.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG-13x.md b/CHANGELOG-13x.md index a280ebfc..f984d2cc 100644 --- a/CHANGELOG-13x.md +++ b/CHANGELOG-13x.md @@ -2,7 +2,13 @@ All notable changes to this project will be documented in this file. -## [Unreleased](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v13.0.1...master) +## [Unreleased](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v13.1.0...master) + +## [31.1.0] (2023-01-25)(https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v13.0.1...v13.1.0) + +- Fix delay parameter not being used [#502](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/502) +- Resolve Laravel 9 incompatabilities [#502](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/502) +- Fix Horizon invalid delay property [#502](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/502) ## [13.0.1 (2022-09-16)](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v13.0.0...v13.0.1) From 1adc8958e65f1820b340c8e1397d1480e1980f6c Mon Sep 17 00:00:00 2001 From: Matthew Porter Date: Wed, 25 Jan 2023 11:45:00 -0700 Subject: [PATCH 019/150] Fix changelog --- CHANGELOG-13x.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG-13x.md b/CHANGELOG-13x.md index f984d2cc..0f9e7678 100644 --- a/CHANGELOG-13x.md +++ b/CHANGELOG-13x.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. ## [Unreleased](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v13.1.0...master) -## [31.1.0] (2023-01-25)(https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v13.0.1...v13.1.0) +## [13.1.0 (2023-01-25)](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v13.0.1...v13.1.0) - Fix delay parameter not being used [#502](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/502) - Resolve Laravel 9 incompatabilities [#502](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/502) From 151d9527c271d544fbdc3e81ff604d381a31276d Mon Sep 17 00:00:00 2001 From: Morten Hauberg-Lund Date: Thu, 26 Jan 2023 06:29:03 +0100 Subject: [PATCH 020/150] Use `queue:work` for multi queue consuming --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9d889808..df0ac4ff 100644 --- a/README.md +++ b/README.md @@ -268,7 +268,7 @@ $app->register(VladimirYuldashev\LaravelQueueRabbitMQ\LaravelQueueRabbitMQServic There are two ways of consuming messages. -1. `queue:work` command which is Laravel's built-in command. This command utilizes `basic_get`. +1. `queue:work` command which is Laravel's built-in command. This command utilizes `basic_get`. Use this if you want to consume multiple queues. 2. `rabbitmq:consume` command which is provided by this package. This command utilizes `basic_consume` and is more performant than `basic_get` by ~2x, but does not support multiple queues. From 5bc3a526c15e758cedd56f19a52874b5efb40d3a Mon Sep 17 00:00:00 2001 From: Seb Date: Tue, 21 Feb 2023 12:57:06 -0800 Subject: [PATCH 021/150] Enable PHP 8.2 in tests --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 702bfe9b..5633c682 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,7 +13,7 @@ jobs: strategy: fail-fast: true matrix: - php: ['8.0', '8.1'] + php: ['8.0', '8.1', '8.2'] stability: [prefer-lowest, prefer-stable] name: PHP ${{ matrix.php }} - ${{ matrix.stability }} From eb397a0015c8657b7a37e8d4fe79cff9b5f0e3aa Mon Sep 17 00:00:00 2001 From: Seb Date: Tue, 21 Feb 2023 12:57:42 -0800 Subject: [PATCH 022/150] fix pint linter issues --- src/Console/ExchangeDeclareCommand.php | 2 - src/Console/ExchangeDeleteCommand.php | 2 - src/Console/QueueBindCommand.php | 2 - src/Console/QueueDeclareCommand.php | 2 - src/Console/QueueDeleteCommand.php | 2 - src/Console/QueuePurgeCommand.php | 2 - src/Consumer.php | 3 - src/Horizon/Listeners/RabbitMQFailedEvent.php | 4 - src/Horizon/RabbitMQQueue.php | 3 - src/LaravelQueueRabbitMQServiceProvider.php | 4 - src/Queue/Connectors/RabbitMQConnector.php | 12 -- src/Queue/Jobs/RabbitMQJob.php | 6 - src/Queue/RabbitMQQueue.php | 106 ------------------ tests/Functional/TestCase.php | 3 - 14 files changed, 153 deletions(-) diff --git a/src/Console/ExchangeDeclareCommand.php b/src/Console/ExchangeDeclareCommand.php index 99f0b753..43aa9c5c 100644 --- a/src/Console/ExchangeDeclareCommand.php +++ b/src/Console/ExchangeDeclareCommand.php @@ -18,8 +18,6 @@ class ExchangeDeclareCommand extends Command protected $description = 'Declare exchange'; /** - * @param RabbitMQConnector $connector - * * @throws Exception */ public function handle(RabbitMQConnector $connector): void diff --git a/src/Console/ExchangeDeleteCommand.php b/src/Console/ExchangeDeleteCommand.php index 904f38ba..d5a8d8d4 100644 --- a/src/Console/ExchangeDeleteCommand.php +++ b/src/Console/ExchangeDeleteCommand.php @@ -16,8 +16,6 @@ class ExchangeDeleteCommand extends Command protected $description = 'Delete exchange'; /** - * @param RabbitMQConnector $connector - * * @throws Exception */ public function handle(RabbitMQConnector $connector): void diff --git a/src/Console/QueueBindCommand.php b/src/Console/QueueBindCommand.php index 40799460..ccbbd706 100644 --- a/src/Console/QueueBindCommand.php +++ b/src/Console/QueueBindCommand.php @@ -17,8 +17,6 @@ class QueueBindCommand extends Command protected $description = 'Bind queue to exchange'; /** - * @param RabbitMQConnector $connector - * * @throws Exception */ public function handle(RabbitMQConnector $connector): void diff --git a/src/Console/QueueDeclareCommand.php b/src/Console/QueueDeclareCommand.php index d43f49ce..54d6ea32 100644 --- a/src/Console/QueueDeclareCommand.php +++ b/src/Console/QueueDeclareCommand.php @@ -19,8 +19,6 @@ class QueueDeclareCommand extends Command protected $description = 'Declare queue'; /** - * @param RabbitMQConnector $connector - * * @throws Exception */ public function handle(RabbitMQConnector $connector): void diff --git a/src/Console/QueueDeleteCommand.php b/src/Console/QueueDeleteCommand.php index 8bca7c20..b2586ecd 100644 --- a/src/Console/QueueDeleteCommand.php +++ b/src/Console/QueueDeleteCommand.php @@ -17,8 +17,6 @@ class QueueDeleteCommand extends Command protected $description = 'Delete queue'; /** - * @param RabbitMQConnector $connector - * * @throws Exception */ public function handle(RabbitMQConnector $connector): void diff --git a/src/Console/QueuePurgeCommand.php b/src/Console/QueuePurgeCommand.php index 95b765ea..49be839b 100644 --- a/src/Console/QueuePurgeCommand.php +++ b/src/Console/QueuePurgeCommand.php @@ -19,8 +19,6 @@ class QueuePurgeCommand extends Command protected $description = 'Purge all messages in queue'; /** - * @param RabbitMQConnector $connector - * * @throws Exception */ public function handle(RabbitMQConnector $connector): void diff --git a/src/Consumer.php b/src/Consumer.php index d27b96c4..bd7f099d 100644 --- a/src/Consumer.php +++ b/src/Consumer.php @@ -65,7 +65,6 @@ public function setPrefetchCount(int $value): void * * @param string $connectionName * @param string $queue - * @param WorkerOptions $options * @return int * * @throws Throwable @@ -181,10 +180,8 @@ function (AMQPMessage $message) use ($connection, $options, $connectionName, $qu /** * Determine if the daemon should process on this iteration. * - * @param WorkerOptions $options * @param string $connectionName * @param string $queue - * @return bool */ protected function daemonShouldRun(WorkerOptions $options, $connectionName, $queue): bool { diff --git a/src/Horizon/Listeners/RabbitMQFailedEvent.php b/src/Horizon/Listeners/RabbitMQFailedEvent.php index 1edfa551..00674827 100644 --- a/src/Horizon/Listeners/RabbitMQFailedEvent.php +++ b/src/Horizon/Listeners/RabbitMQFailedEvent.php @@ -19,7 +19,6 @@ class RabbitMQFailedEvent /** * Create a new listener instance. * - * @param Dispatcher $events * @return void */ public function __construct(Dispatcher $events) @@ -29,9 +28,6 @@ public function __construct(Dispatcher $events) /** * Handle the event. - * - * @param LaravelJobFailed $event - * @return void */ public function handle(LaravelJobFailed $event): void { diff --git a/src/Horizon/RabbitMQQueue.php b/src/Horizon/RabbitMQQueue.php index bf5b2ee2..7b038003 100644 --- a/src/Horizon/RabbitMQQueue.php +++ b/src/Horizon/RabbitMQQueue.php @@ -26,7 +26,6 @@ class RabbitMQQueue extends BaseRabbitMQQueue * Get the number of queue jobs that are ready to process. * * @param string|null $queue - * @return int * * @throws AMQPProtocolChannelException */ @@ -96,7 +95,6 @@ public function release($delay, $job, $data, $queue, $attempts = 0) * * @param string $queue * @param RabbitMQJob $job - * @return void * * @throws BindingResolutionException */ @@ -110,7 +108,6 @@ public function deleteReserved($queue, $job): void * * @param string $queue * @param mixed $event - * @return void * * @throws BindingResolutionException */ diff --git a/src/LaravelQueueRabbitMQServiceProvider.php b/src/LaravelQueueRabbitMQServiceProvider.php index 3be0fd81..ee46d6cd 100644 --- a/src/LaravelQueueRabbitMQServiceProvider.php +++ b/src/LaravelQueueRabbitMQServiceProvider.php @@ -12,8 +12,6 @@ class LaravelQueueRabbitMQServiceProvider extends ServiceProvider { /** * Register the service provider. - * - * @return void */ public function register(): void { @@ -60,8 +58,6 @@ public function register(): void /** * Register the application's event listeners. - * - * @return void */ public function boot(): void { diff --git a/src/Queue/Connectors/RabbitMQConnector.php b/src/Queue/Connectors/RabbitMQConnector.php index 903e1d3a..9fc8615f 100644 --- a/src/Queue/Connectors/RabbitMQConnector.php +++ b/src/Queue/Connectors/RabbitMQConnector.php @@ -31,7 +31,6 @@ public function __construct(Dispatcher $dispatcher) /** * Establish a queue connection. * - * @param array $config * @return RabbitMQQueue * * @throws Exception @@ -64,9 +63,6 @@ public function connect(array $config): Queue } /** - * @param array $config - * @return AbstractConnection - * * @throws Exception */ protected function createConnection(array $config): AbstractConnection @@ -86,11 +82,6 @@ protected function createConnection(array $config): AbstractConnection /** * Create a queue for the worker. * - * @param string $worker - * @param AbstractConnection $connection - * @param string $queue - * @param bool $dispatchAfterCommit - * @param array $options * @return HorizonRabbitMQQueue|RabbitMQQueue|Queue */ protected function createQueue( @@ -112,9 +103,6 @@ protected function createQueue( /** * Recursively filter only null values. - * - * @param array $array - * @return array */ private function filter(array $array): array { diff --git a/src/Queue/Jobs/RabbitMQJob.php b/src/Queue/Jobs/RabbitMQJob.php index 4176d80d..abcdfab4 100644 --- a/src/Queue/Jobs/RabbitMQJob.php +++ b/src/Queue/Jobs/RabbitMQJob.php @@ -137,8 +137,6 @@ public function release($delay = 0): void /** * Get the underlying RabbitMQ connection. - * - * @return RabbitMQQueue */ public function getRabbitMQ(): RabbitMQQueue { @@ -147,8 +145,6 @@ public function getRabbitMQ(): RabbitMQQueue /** * Get the underlying RabbitMQ message. - * - * @return AMQPMessage */ public function getRabbitMQMessage(): AMQPMessage { @@ -157,8 +153,6 @@ public function getRabbitMQMessage(): AMQPMessage /** * Get the headers from the rabbitMQ message. - * - * @return array|null */ protected function getRabbitMQMessageHeaders(): ?array { diff --git a/src/Queue/RabbitMQQueue.php b/src/Queue/RabbitMQQueue.php index 38ad1e94..030a4734 100644 --- a/src/Queue/RabbitMQQueue.php +++ b/src/Queue/RabbitMQQueue.php @@ -81,11 +81,6 @@ class RabbitMQQueue extends Queue implements QueueContract /** * RabbitMQQueue constructor. - * - * @param AbstractConnection $connection - * @param string $default - * @param bool $dispatchAfterCommit - * @param array $options */ public function __construct( AbstractConnection $connection, @@ -176,8 +171,6 @@ function ($payload, $queue, $delay) { } /** - * @param $delay - * @param $payload * @param null $queue * @param int $attempts * @return mixed @@ -227,9 +220,7 @@ public function bulk($jobs, $data = '', $queue = null): void } /** - * @param string $payload * @param null $queue - * @param array $options * @return mixed * * @throws AMQPProtocolChannelException @@ -296,17 +287,11 @@ public function pop($queue = null) return null; } - /** - * @return AbstractConnection - */ public function getConnection(): AbstractConnection { return $this->connection; } - /** - * @return AMQPChannel - */ public function getChannel(): AMQPChannel { return $this->channel; @@ -315,7 +300,6 @@ public function getChannel(): AMQPChannel /** * Job class to use. * - * @return string * * @throws Throwable */ @@ -336,7 +320,6 @@ public function getJobClass(): string * Gets a queue/destination, by default the queue option set on the connection. * * @param null $queue - * @return string */ public function getQueue($queue = null): string { @@ -347,8 +330,6 @@ public function getQueue($queue = null): string * Checks if the given exchange already present/defined in RabbitMQ. * Returns false when when the exchange is missing. * - * @param string $exchange - * @return bool * * @throws AMQPProtocolChannelException */ @@ -378,13 +359,6 @@ public function isExchangeExists(string $exchange): bool /** * Declare a exchange in rabbitMQ, when not already declared. - * - * @param string $name - * @param string $type - * @param bool $durable - * @param bool $autoDelete - * @param array $arguments - * @return void */ public function declareExchange( string $name, @@ -412,9 +386,6 @@ public function declareExchange( /** * Delete a exchange from rabbitMQ, only when present in RabbitMQ. * - * @param string $name - * @param bool $unused - * @return void * * @throws AMQPProtocolChannelException */ @@ -437,8 +408,6 @@ public function deleteExchange(string $name, bool $unused = false): void * Checks if the given queue already present/defined in RabbitMQ. * Returns false when when the queue is missing. * - * @param string|null $name - * @return bool * * @throws AMQPProtocolChannelException */ @@ -462,12 +431,6 @@ public function isQueueExists(string $name = null): bool /** * Declare a queue in rabbitMQ, when not already declared. - * - * @param string $name - * @param bool $durable - * @param bool $autoDelete - * @param array $arguments - * @return void */ public function declareQueue( string $name, @@ -493,10 +456,6 @@ public function declareQueue( /** * Delete a queue from rabbitMQ, only when present in RabbitMQ. * - * @param string $name - * @param bool $if_unused - * @param bool $if_empty - * @return void * * @throws AMQPProtocolChannelException */ @@ -511,11 +470,6 @@ public function deleteQueue(string $name, bool $if_unused = false, bool $if_empt /** * Bind a queue to an exchange. - * - * @param string $queue - * @param string $exchange - * @param string $routingKey - * @return void */ public function bindQueue(string $queue, string $exchange, string $routingKey = ''): void { @@ -532,9 +486,6 @@ public function bindQueue(string $queue, string $exchange, string $routingKey = /** * Purge the queue of messages. - * - * @param string|null $queue - * @return void */ public function purge(string $queue = null): void { @@ -546,9 +497,6 @@ public function purge(string $queue = null): void /** * Acknowledge the message. - * - * @param RabbitMQJob $job - * @return void */ public function ack(RabbitMQJob $job): void { @@ -557,10 +505,6 @@ public function ack(RabbitMQJob $job): void /** * Reject the message. - * - * @param RabbitMQJob $job - * @param bool $requeue - * @return void */ public function reject(RabbitMQJob $job, bool $requeue = false): void { @@ -570,9 +514,6 @@ public function reject(RabbitMQJob $job, bool $requeue = false): void /** * Create a AMQP message. * - * @param $payload - * @param int $attempts - * @return array * * @throws JsonException */ @@ -619,7 +560,6 @@ protected function createMessage($payload, int $attempts = 0): array * @param string|object $job * @param string $queue * @param mixed $data - * @return array */ protected function createPayloadArray($job, $queue, $data = ''): array { @@ -630,8 +570,6 @@ protected function createPayloadArray($job, $queue, $data = ''): array /** * Get a random ID string. - * - * @return string */ protected function getRandomId(): string { @@ -641,7 +579,6 @@ protected function getRandomId(): string /** * Close the connection to RabbitMQ. * - * @return void * * @throws Exception */ @@ -660,9 +597,6 @@ public function close(): void /** * Get the Queue arguments. - * - * @param string $destination - * @return array */ protected function getQueueArguments(string $destination): array { @@ -690,10 +624,6 @@ protected function getQueueArguments(string $destination): array /** * Get the Delay queue arguments. - * - * @param string $destination - * @param int $ttl - * @return array */ protected function getDelayQueueArguments(string $destination, int $ttl): array { @@ -707,8 +637,6 @@ protected function getDelayQueueArguments(string $destination, int $ttl): array /** * Returns &true;, if delayed messages should be prioritized. - * - * @return bool */ protected function isPrioritizeDelayed(): bool { @@ -721,8 +649,6 @@ protected function isPrioritizeDelayed(): bool * Using more priority layers, will consume more CPU resources and would affect runtimes. * * @see https://www.rabbitmq.com/priority.html - * - * @return int */ protected function getQueueMaxPriority(): int { @@ -731,9 +657,6 @@ protected function getQueueMaxPriority(): int /** * Get the exchange name, or &null; as default value. - * - * @param string|null $exchange - * @return string|null */ protected function getExchange(string $exchange = null): ?string { @@ -743,9 +666,6 @@ protected function getExchange(string $exchange = null): ?string /** * Get the routing-key for when you use exchanges * The default routing-key is the given destination. - * - * @param string $destination - * @return string */ protected function getRoutingKey(string $destination): string { @@ -754,9 +674,6 @@ protected function getRoutingKey(string $destination): string /** * Get the exchangeType, or AMQPExchangeType::DIRECT as default. - * - * @param string|null $type - * @return string */ protected function getExchangeType(?string $type = null): string { @@ -768,8 +685,6 @@ protected function getExchangeType(?string $type = null): string /** * Returns &true;, if failed messages should be rerouted. - * - * @return bool */ protected function isRerouteFailed(): bool { @@ -778,8 +693,6 @@ protected function isRerouteFailed(): bool /** * Returns &true;, if declared queue must be quorum queue. - * - * @return bool */ protected function isQuorum(): bool { @@ -788,9 +701,6 @@ protected function isQuorum(): bool /** * Get the exchange for failed messages. - * - * @param string|null $exchange - * @return string|null */ protected function getFailedExchange(string $exchange = null): ?string { @@ -800,9 +710,6 @@ protected function getFailedExchange(string $exchange = null): ?string /** * Get the routing-key for failed messages * The default routing-key is the given destination substituted by '.failed'. - * - * @param string $destination - * @return string */ protected function getFailedRoutingKey(string $destination): string { @@ -811,9 +718,6 @@ protected function getFailedRoutingKey(string $destination): string /** * Checks if the exchange was already declared. - * - * @param string $name - * @return bool */ protected function isExchangeDeclared(string $name): bool { @@ -822,9 +726,6 @@ protected function isExchangeDeclared(string $name): bool /** * Checks if the queue was already declared. - * - * @param string $name - * @return bool */ protected function isQueueDeclared(string $name): bool { @@ -834,10 +735,7 @@ protected function isQueueDeclared(string $name): bool /** * Declare the destination when necessary. * - * @param string $destination - * @param string|null $exchange * @param string|null $exchangeType - * @return void * * @throws AMQPProtocolChannelException */ @@ -867,10 +765,6 @@ protected function declareDestination( /** * Determine all publish properties. - * - * @param $queue - * @param array $options - * @return array */ protected function publishProperties($queue, array $options = []): array { diff --git a/tests/Functional/TestCase.php b/tests/Functional/TestCase.php index 40e3e116..01b3c069 100644 --- a/tests/Functional/TestCase.php +++ b/tests/Functional/TestCase.php @@ -161,9 +161,6 @@ protected function getEnvironmentSetUp($app): void } /** - * @param $object - * @param string $method - * @param array $parameters * @return mixed * * @throws Exception From 2d4eb2f92a0d5d49d810128f782df17d5fe328a8 Mon Sep 17 00:00:00 2001 From: Seb Date: Tue, 21 Feb 2023 13:37:57 -0800 Subject: [PATCH 023/150] try enabling laravel 10 --- .github/workflows/tests.yml | 6 +++++- composer.json | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5633c682..1c4400bf 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -15,6 +15,10 @@ jobs: matrix: php: ['8.0', '8.1', '8.2'] stability: [prefer-lowest, prefer-stable] + laravel: ['^9.0', '^10.0'] + exclude: + - php: '8.0' + laravel: '^10.0' name: PHP ${{ matrix.php }} - ${{ matrix.stability }} @@ -40,7 +44,7 @@ jobs: run: docker-compose up -d rabbitmq - name: Install dependencies - run: composer update --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress + run: composer update --with='illuminate/queue:${{matrix.laravel}}' --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress - name: Run Laravel Pint run: ./vendor/bin/pint --test diff --git a/composer.json b/composer.json index 15bf6e85..9c3c12cf 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,7 @@ "require": { "php": "^8.0", "ext-json": "*", - "illuminate/queue": "^9.0", + "illuminate/queue": "^9.0|^10.0", "php-amqplib/php-amqplib": "^3.0" }, "require-dev": { From 239110e41e078aa304efa1823b2af80717e225cd Mon Sep 17 00:00:00 2001 From: Seb Date: Tue, 21 Feb 2023 13:39:23 -0800 Subject: [PATCH 024/150] test names --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1c4400bf..f78ab11d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,7 +20,7 @@ jobs: - php: '8.0' laravel: '^10.0' - name: PHP ${{ matrix.php }} - ${{ matrix.stability }} + name: 'PHP ${{ matrix.php }} - ${{ matrix.stability }} - Laravel: ${{matrix.laravel}}' steps: - name: Checkout code From 1a375f3e70249f0c33e97eca064e9eec47acbf2a Mon Sep 17 00:00:00 2001 From: Seb Date: Tue, 21 Feb 2023 14:04:51 -0800 Subject: [PATCH 025/150] enable more lara10 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 9c3c12cf..9833f04e 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "phpunit/phpunit": "^9.3", "mockery/mockery": "^1.0", "laravel/horizon": "^5.0", - "orchestra/testbench": "^7.0", + "orchestra/testbench": "^7.0|^8.0", "laravel/pint": "^1.2" }, "autoload": { From 07a834fb80e4feb35c6e81554a8e0a1e38b85686 Mon Sep 17 00:00:00 2001 From: Seb Date: Tue, 21 Feb 2023 14:06:49 -0800 Subject: [PATCH 026/150] stability last in name --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f78ab11d..5178bcf2 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,7 +20,7 @@ jobs: - php: '8.0' laravel: '^10.0' - name: 'PHP ${{ matrix.php }} - ${{ matrix.stability }} - Laravel: ${{matrix.laravel}}' + name: 'PHP ${{ matrix.php }} - Laravel: ${{matrix.laravel}} - ${{ matrix.stability }}' steps: - name: Checkout code From deac081c9005a59d15b69a4cb4b2591258270e20 Mon Sep 17 00:00:00 2001 From: Seb Date: Tue, 21 Feb 2023 15:28:49 -0800 Subject: [PATCH 027/150] tentative constraint --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5178bcf2..b2660bae 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -15,7 +15,7 @@ jobs: matrix: php: ['8.0', '8.1', '8.2'] stability: [prefer-lowest, prefer-stable] - laravel: ['^9.0', '^10.0'] + laravel: ['^9.0 < 10.0', '^10.0'] exclude: - php: '8.0' laravel: '^10.0' From 9109ba144e48598da2d5a24bb7c439a8c68e761f Mon Sep 17 00:00:00 2001 From: Seb Date: Tue, 21 Feb 2023 15:40:05 -0800 Subject: [PATCH 028/150] stable or nothing --- .github/workflows/tests.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b2660bae..f65bf2e0 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -14,8 +14,8 @@ jobs: fail-fast: true matrix: php: ['8.0', '8.1', '8.2'] - stability: [prefer-lowest, prefer-stable] - laravel: ['^9.0 < 10.0', '^10.0'] + stability: ['', '--prefer-stable'] + laravel: ['^9.0', '^10.0'] exclude: - php: '8.0' laravel: '^10.0' @@ -44,7 +44,7 @@ jobs: run: docker-compose up -d rabbitmq - name: Install dependencies - run: composer update --with='illuminate/queue:${{matrix.laravel}}' --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress + run: composer update --with='illuminate/queue:${{matrix.laravel}}' ${{ matrix.stability }} --prefer-dist --no-interaction --no-progress - name: Run Laravel Pint run: ./vendor/bin/pint --test From 67f3b9f0546e8194e3572eab76e7cbf40e1c1e06 Mon Sep 17 00:00:00 2001 From: Seb Date: Tue, 21 Feb 2023 15:45:01 -0800 Subject: [PATCH 029/150] stable or nothing --- .github/workflows/tests.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f65bf2e0..3ccf92f5 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -14,8 +14,8 @@ jobs: fail-fast: true matrix: php: ['8.0', '8.1', '8.2'] - stability: ['', '--prefer-stable'] - laravel: ['^9.0', '^10.0'] + stability: ['prefer-lowest', prefer-stable] + laravel: ['>=9.0 <10', '^10.0'] exclude: - php: '8.0' laravel: '^10.0' @@ -44,7 +44,7 @@ jobs: run: docker-compose up -d rabbitmq - name: Install dependencies - run: composer update --with='illuminate/queue:${{matrix.laravel}}' ${{ matrix.stability }} --prefer-dist --no-interaction --no-progress + run: composer update --with='illuminate/queue:${{matrix.laravel}}' --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress - name: Run Laravel Pint run: ./vendor/bin/pint --test From 77004c5d0d49e48b129975a0721503561d749392 Mon Sep 17 00:00:00 2001 From: Seb Date: Tue, 21 Feb 2023 15:55:20 -0800 Subject: [PATCH 030/150] was that it --- .github/workflows/tests.yml | 2 +- composer.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3ccf92f5..828d3eef 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -15,7 +15,7 @@ jobs: matrix: php: ['8.0', '8.1', '8.2'] stability: ['prefer-lowest', prefer-stable] - laravel: ['>=9.0 <10', '^10.0'] + laravel: ['^9.0', '^10.0'] exclude: - php: '8.0' laravel: '^10.0' diff --git a/composer.json b/composer.json index 9833f04e..4dbf9b34 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,7 @@ "require": { "php": "^8.0", "ext-json": "*", - "illuminate/queue": "^9.0|^10.0", + "illuminate/queue": "^9.0||^10.0", "php-amqplib/php-amqplib": "^3.0" }, "require-dev": { From babf55f6d64228237bbf6fb06885c247a37b9b30 Mon Sep 17 00:00:00 2001 From: Seb Date: Tue, 21 Feb 2023 15:59:55 -0800 Subject: [PATCH 031/150] use as direct dependency to force it --- .github/workflows/tests.yml | 2 +- composer.json | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 828d3eef..37c80375 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -44,7 +44,7 @@ jobs: run: docker-compose up -d rabbitmq - name: Install dependencies - run: composer update --with='illuminate/queue:${{matrix.laravel}}' --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress + run: composer update --with='laravel/framework:${{matrix.laravel}}' --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress - name: Run Laravel Pint run: ./vendor/bin/pint --test diff --git a/composer.json b/composer.json index 4dbf9b34..5461314d 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,7 @@ "require": { "php": "^8.0", "ext-json": "*", - "illuminate/queue": "^9.0||^10.0", + "illuminate/queue": "^9.0|^10.0", "php-amqplib/php-amqplib": "^3.0" }, "require-dev": { @@ -19,7 +19,8 @@ "mockery/mockery": "^1.0", "laravel/horizon": "^5.0", "orchestra/testbench": "^7.0|^8.0", - "laravel/pint": "^1.2" + "laravel/pint": "^1.2", + "laravel/framework": "^9.0|^10.0" }, "autoload": { "psr-4": { From 0cccc92794b4d85268ff9e6a74293deb97de8245 Mon Sep 17 00:00:00 2001 From: Seb Date: Wed, 22 Feb 2023 10:42:55 -0800 Subject: [PATCH 032/150] update readme --- CHANGELOG-13x.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG-13x.md b/CHANGELOG-13x.md index 0f9e7678..0631fc9d 100644 --- a/CHANGELOG-13x.md +++ b/CHANGELOG-13x.md @@ -2,7 +2,11 @@ All notable changes to this project will be documented in this file. -## [Unreleased](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v13.1.0...master) +## [unreleased](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v13.2.0...master) + +## [13.2.0](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v13.1.0...13.2.0) + +- Compatibility with Laravel 10 [#525](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/525) ## [13.1.0 (2023-01-25)](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v13.0.1...v13.1.0) From f2f7a5e7a907ad2bb39fe0113add5220ead82338 Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Thu, 2 Mar 2023 19:09:23 +0100 Subject: [PATCH 033/150] added: - factory for making a queue. - default config object - rabbitmq queue contract fixed: - code quality issues - tests (for checking moved config items) removed: - unnecessary config - unnecessary methods for returning just the config --- config/rabbitmq.php | 4 +- src/Contracts/RabbitMQQueueContract.php | 14 ++ src/Horizon/RabbitMQQueue.php | 25 +-- src/Queue/Connectors/RabbitMQConnector.php | 45 +---- src/Queue/QueueConfig.php | 213 +++++++++++++++++++++ src/Queue/QueueFactory.php | 65 +++++++ src/Queue/RabbitMQQueue.php | 210 +++++++------------- tests/Functional/RabbitMQQueueTest.php | 81 ++++---- 8 files changed, 415 insertions(+), 242 deletions(-) create mode 100644 src/Contracts/RabbitMQQueueContract.php create mode 100644 src/Queue/QueueConfig.php create mode 100644 src/Queue/QueueFactory.php diff --git a/config/rabbitmq.php b/config/rabbitmq.php index d5390a5c..900e3b74 100644 --- a/config/rabbitmq.php +++ b/config/rabbitmq.php @@ -29,9 +29,7 @@ 'verify_peer' => env('RABBITMQ_SSL_VERIFY_PEER', true), 'passphrase' => env('RABBITMQ_SSL_PASSPHRASE', null), ], - 'queue' => [ - 'job' => VladimirYuldashev\LaravelQueueRabbitMQ\Queue\Jobs\RabbitMQJob::class, - ], + 'queue' => [], ], /* diff --git a/src/Contracts/RabbitMQQueueContract.php b/src/Contracts/RabbitMQQueueContract.php new file mode 100644 index 00000000..cf04a66e --- /dev/null +++ b/src/Contracts/RabbitMQQueueContract.php @@ -0,0 +1,14 @@ +size($queue); } @@ -46,8 +43,10 @@ public function push($job, $data = '', $queue = null) /** * {@inheritdoc} + * + * @throws BindingResolutionException */ - public function pushRaw($payload, $queue = null, array $options = []) + public function pushRaw($payload, $queue = null, array $options = []): int|string|null { $payload = (new JobPayload($payload))->prepare($this->lastPushed)->value; @@ -58,8 +57,10 @@ public function pushRaw($payload, $queue = null, array $options = []) /** * {@inheritdoc} + * + * @throws BindingResolutionException */ - public function later($delay, $job, $data = '', $queue = null) + public function later($delay, $job, $data = '', $queue = null): mixed { $payload = (new JobPayload($this->createPayload($job, $data)))->prepare($job)->value; @@ -80,16 +81,6 @@ public function pop($queue = null) }); } - /** - * {@inheritdoc} - */ - public function release($delay, $job, $data, $queue, $attempts = 0) - { - $this->lastPushed = $job; - - return parent::release($delay, $job, $data, $queue, $attempts); - } - /** * Fire the job deleted event. * diff --git a/src/Queue/Connectors/RabbitMQConnector.php b/src/Queue/Connectors/RabbitMQConnector.php index 9fc8615f..8d8498b4 100644 --- a/src/Queue/Connectors/RabbitMQConnector.php +++ b/src/Queue/Connectors/RabbitMQConnector.php @@ -9,23 +9,23 @@ use Illuminate\Queue\Events\JobFailed; use Illuminate\Queue\Events\WorkerStopping; use Illuminate\Support\Arr; -use InvalidArgumentException; use PhpAmqpLib\Connection\AbstractConnection; use PhpAmqpLib\Connection\AMQPLazyConnection; use VladimirYuldashev\LaravelQueueRabbitMQ\Horizon\Listeners\RabbitMQFailedEvent; use VladimirYuldashev\LaravelQueueRabbitMQ\Horizon\RabbitMQQueue as HorizonRabbitMQQueue; +use VladimirYuldashev\LaravelQueueRabbitMQ\Queue\QueueFactory; use VladimirYuldashev\LaravelQueueRabbitMQ\Queue\RabbitMQQueue; class RabbitMQConnector implements ConnectorInterface { - /** - * @var Dispatcher - */ - private $dispatcher; + private Dispatcher $dispatcher; + + private QueueFactory $queue; public function __construct(Dispatcher $dispatcher) { $this->dispatcher = $dispatcher; + $this->queue = new QueueFactory(); } /** @@ -37,19 +37,10 @@ public function __construct(Dispatcher $dispatcher) */ public function connect(array $config): Queue { + // Todo Create ConnectionFactory removing all deprecated dependicies $connection = $this->createConnection(Arr::except($config, 'options.queue')); - $queue = $this->createQueue( - Arr::get($config, 'worker', 'default'), - $connection, - $config['queue'], - Arr::get($config, 'after_commit', false), - Arr::get($config, 'options.queue', []) - ); - - if (! $queue instanceof RabbitMQQueue) { - throw new InvalidArgumentException('Invalid worker.'); - } + $queue = $this->queue->make($config)->setConnection($connection); if ($queue instanceof HorizonRabbitMQQueue) { $this->dispatcher->listen(JobFailed::class, RabbitMQFailedEvent::class); @@ -79,28 +70,6 @@ protected function createConnection(array $config): AbstractConnection ); } - /** - * Create a queue for the worker. - * - * @return HorizonRabbitMQQueue|RabbitMQQueue|Queue - */ - protected function createQueue( - string $worker, - AbstractConnection $connection, - string $queue, - bool $dispatchAfterCommit, - array $options = [] - ) { - switch ($worker) { - case 'default': - return new RabbitMQQueue($connection, $queue, $dispatchAfterCommit, $options); - case 'horizon': - return new HorizonRabbitMQQueue($connection, $queue, $dispatchAfterCommit, $options); - default: - return new $worker($connection, $queue, $options); - } - } - /** * Recursively filter only null values. */ diff --git a/src/Queue/QueueConfig.php b/src/Queue/QueueConfig.php new file mode 100644 index 00000000..6c4b5d49 --- /dev/null +++ b/src/Queue/QueueConfig.php @@ -0,0 +1,213 @@ +queue; + } + + public function setQueue(?string $queue): QueueConfig + { + $this->queue = $queue ?: 'default'; + + return $this; + } + + public function isDispatchAfterCommit(): bool + { + return $this->dispatchAfterCommit; + } + + public function setDispatchAfterCommit($dispatchAfterCommit): QueueConfig + { + $this->dispatchAfterCommit = ! empty($dispatchAfterCommit); + + return $this; + } + + public function getOptions(): array + { + return $this->options; + } + + public function setOptions(?array $options): QueueConfig + { + $this->options = $options ?: []; + + return $this; + } + + public function getAbstractJob(): string + { + return $this->abstractJob; + } + + public function setAbstractJob(?string $abstract): QueueConfig + { + $this->abstractJob = $abstract ?: RabbitMQJob::class; + + return $this; + } + + /** + * Returns &true;, if delayed messages should be prioritized. + */ + public function isPrioritizeDelayed(): bool + { + return $this->prioritizeDelayed; + } + + public function setPrioritizeDelayed($prioritizeDelayed): QueueConfig + { + $this->prioritizeDelayed = ! empty($prioritizeDelayed); + + return $this; + } + + /** + * Returns a integer with a default of '2' for when using prioritization on delayed messages. + * If priority queues are desired, we recommend using between 1 and 10. + * Using more priority layers, will consume more CPU resources and would affect runtimes. + * + * @see https://www.rabbitmq.com/priority.html + */ + public function getQueueMaxPriority(): int + { + return $this->queueMaxPriority; + } + + public function setQueueMaxPriority($queueMaxPriority): QueueConfig + { + $this->queueMaxPriority = is_numeric($queueMaxPriority) ? (int) $queueMaxPriority : 2; + + return $this; + } + + /** + * Get the exchange name, or &null; as default value. + */ + public function getExchange(): ?string + { + return $this->exchange; + } + + public function setExchange(?string $exchange): QueueConfig + { + $this->exchange = $exchange ?: null; + + return $this; + } + + public function getExchangeType(): string + { + return $this->exchangeType; + } + + public function setExchangeType(?string $exchangeType): QueueConfig + { + $this->exchangeType = $exchangeType ?: 'direct'; + + return $this; + } + + /** + * @return string + */ + public function getExchangeRoutingKey(): ?string + { + return $this->exchangeRoutingKey; + } + + public function setExchangeRoutingKey(?string $exchangeRoutingKey): QueueConfig + { + $this->exchangeRoutingKey = $exchangeRoutingKey ?: '%s'; + + return $this; + } + + /** + * Returns &true;, if failed messages should be rerouted. + */ + public function isRerouteFailed(): bool + { + return $this->rerouteFailed; + } + + public function setRerouteFailed($rerouteFailed): QueueConfig + { + $this->rerouteFailed = ! empty($rerouteFailed); + + return $this; + } + + public function getFailedExchange(): ?string + { + return $this->failedExchange; + } + + public function setFailedExchange(?string $failedExchange): QueueConfig + { + $this->failedExchange = $failedExchange ?: null; + + return $this; + } + + /** + * Get the routing-key for failed messages + * The default routing-key is the given destination substituted by '.failed'. + */ + public function getFailedRoutingKey(): string + { + return $this->failedRoutingKey; + } + + public function setFailedRoutingKey(?string $failedRoutingKey): QueueConfig + { + $this->failedRoutingKey = $failedRoutingKey ?: '%s.failed'; + + return $this; + } + + public function isQuorum(): bool + { + return $this->quorum; + } + + public function setQuorum($quorum): QueueConfig + { + $this->quorum = ! empty($quorum); + + return $this; + } +} diff --git a/src/Queue/QueueFactory.php b/src/Queue/QueueFactory.php new file mode 100644 index 00000000..ccbfd51d --- /dev/null +++ b/src/Queue/QueueFactory.php @@ -0,0 +1,65 @@ +createQueueConfig($config); + $worker = Arr::get($config, 'worker', 'default'); + + if (strtolower($worker) == 'default') { + return $this->queue = new RabbitMQQueue($queueConfig); + } + + if (strtolower($worker) == 'horizon') { + return $this->queue = new HorizonRabbitMQQueue($queueConfig); + } + + return $this->queue = new $worker($queueConfig); + } + + /** + * Create a config object from config array + */ + private function createQueueConfig(array $config = []): QueueConfig + { + return tap(new QueueConfig(), function (QueueConfig $queueConfig) use ($config) { + if (! empty($queue = Arr::get($config, 'queue'))) { + $queueConfig->setQueue($queue); + } + if (! empty($afterCommit = Arr::get($config, 'after_commit'))) { + $queueConfig->setDispatchAfterCommit($afterCommit); + } + + if (! empty($queueOptionsConfig = Arr::get($config, 'options.queue'))) { + $queueConfig + ->setAbstractJob(Arr::pull($queueOptionsConfig, 'job')) + // Feature: Prioritize delayed messages. + ->setPrioritizeDelayed(Arr::pull($queueOptionsConfig, 'prioritize_delayed')) + ->setQueueMaxPriority(Arr::pull($queueOptionsConfig, 'queue_max_priority')) + // Feature: Working with Exchange and routing-keys + ->setExchange(Arr::pull($queueOptionsConfig, 'exchange')) + ->setExchangeType(Arr::pull($queueOptionsConfig, 'exchange_type')) + ->setExchangeRoutingKey(Arr::pull($queueOptionsConfig, 'exchange_routing_key')) + // Feature: Reroute failed messages + ->setRerouteFailed(Arr::pull($queueOptionsConfig, 'reroute_failed')) + ->setFailedExchange(Arr::pull($queueOptionsConfig, 'failed_exchange')) + ->setFailedRoutingKey(Arr::pull($queueOptionsConfig, 'failed_routing_key')) + // Feature: Mark queue as quorum + ->setQuorum(Arr::pull($queueOptionsConfig, 'quorum')) + // All extra options not defined + ->setOptions($queueOptionsConfig); + } + }); + } +} diff --git a/src/Queue/RabbitMQQueue.php b/src/Queue/RabbitMQQueue.php index 030a4734..59d98f3a 100644 --- a/src/Queue/RabbitMQQueue.php +++ b/src/Queue/RabbitMQQueue.php @@ -10,7 +10,6 @@ use Illuminate\Queue\Queue; use Illuminate\Support\Arr; use Illuminate\Support\Str; -use JsonException; use PhpAmqpLib\Channel\AMQPChannel; use PhpAmqpLib\Connection\AbstractConnection; use PhpAmqpLib\Exception\AMQPChannelClosedException; @@ -21,78 +20,53 @@ use PhpAmqpLib\Message\AMQPMessage; use PhpAmqpLib\Wire\AMQPTable; use Throwable; +use VladimirYuldashev\LaravelQueueRabbitMQ\Contracts\RabbitMQQueueContract; use VladimirYuldashev\LaravelQueueRabbitMQ\Queue\Jobs\RabbitMQJob; -class RabbitMQQueue extends Queue implements QueueContract +class RabbitMQQueue extends Queue implements QueueContract, RabbitMQQueueContract { /** * The RabbitMQ connection instance. - * - * @var AbstractConnection */ - protected $connection; + protected AbstractConnection $connection; /** * The RabbitMQ channel instance. - * - * @var AMQPChannel */ - protected $channel; - - /** - * The name of the default queue. - * - * @var string - */ - protected $default; + protected AMQPChannel $channel; /** * List of already declared exchanges. - * - * @var array */ - protected $exchanges = []; + protected array $exchanges = []; /** * List of already declared queues. - * - * @var array */ - protected $queues = []; + protected array $queues = []; /** * List of already bound queues to exchanges. - * - * @var array */ - protected $boundQueues = []; + protected array $boundQueues = []; /** * Current job being processed. - * - * @var RabbitMQJob */ - protected $currentJob; + protected RabbitMQJob $currentJob; /** - * @var array + * Holds the Configuration */ - protected $options; + protected QueueConfig $config; /** * RabbitMQQueue constructor. */ - public function __construct( - AbstractConnection $connection, - string $default, - bool $dispatchAfterCommit = false, - array $options = [] - ) { - $this->connection = $connection; - $this->channel = $connection->channel(); - $this->default = $default; - $this->options = $options; - $this->dispatchAfterCommit = $dispatchAfterCommit; + public function __construct(QueueConfig $config) + { + $this->config = $config; + $this->dispatchAfterCommit = $config->isDispatchAfterCommit(); } /** @@ -109,7 +83,7 @@ public function size($queue = null): int } // create a temporary channel, so the main channel will not be closed on exception - $channel = $this->connection->channel(); + $channel = $this->getConnection()->channel(); [, $size] = $channel->queue_declare($queue, true); $channel->close(); @@ -139,7 +113,7 @@ function ($payload, $queue) { * * @throws AMQPProtocolChannelException */ - public function pushRaw($payload, $queue = null, array $options = []) + public function pushRaw($payload, $queue = null, array $options = []): int|string|null { [$destination, $exchange, $exchangeType, $attempts] = $this->publishProperties($queue, $options); @@ -147,7 +121,7 @@ public function pushRaw($payload, $queue = null, array $options = []) [$message, $correlationId] = $this->createMessage($payload, $attempts); - $this->channel->basic_publish($message, $exchange, $destination, true, false); + $this->getChannel()->basic_publish($message, $exchange, $destination, true); return $correlationId; } @@ -157,7 +131,7 @@ public function pushRaw($payload, $queue = null, array $options = []) * * @throws AMQPProtocolChannelException */ - public function later($delay, $job, $data = '', $queue = null) + public function later($delay, $job, $data = '', $queue = null): mixed { return $this->enqueueUsing( $job, @@ -172,12 +146,10 @@ function ($payload, $queue, $delay) { /** * @param null $queue - * @param int $attempts - * @return mixed * * @throws AMQPProtocolChannelException */ - public function laterRaw($delay, $payload, $queue = null, $attempts = 0) + public function laterRaw($delay, string $payload, $queue = null, int $attempts = 0): int|string|null { $ttl = $this->secondsUntil($delay) * 1000; @@ -199,8 +171,8 @@ public function laterRaw($delay, $payload, $queue = null, $attempts = 0) [$message, $correlationId] = $this->createMessage($payload, $attempts); - // Publish directly on the delayQueue, no need to publish trough an exchange. - $this->channel->basic_publish($message, null, $destination, true, false); + // Publish directly on the delayQueue, no need to publish through an exchange. + $this->getChannel()->basic_publish($message, null, $destination, true); return $correlationId; } @@ -216,16 +188,13 @@ public function bulk($jobs, $data = '', $queue = null): void $this->bulkRaw($this->createPayload($job, $queue, $data), $queue, ['job' => $job]); } - $this->channel->publish_batch(); + $this->getChannel()->publish_batch(); } /** - * @param null $queue - * @return mixed - * * @throws AMQPProtocolChannelException */ - public function bulkRaw(string $payload, $queue = null, array $options = []) + public function bulkRaw(string $payload, string $queue = null, array $options = []): int|string|null { [$destination, $exchange, $exchangeType, $attempts] = $this->publishProperties($queue, $options); @@ -233,7 +202,7 @@ public function bulkRaw(string $payload, $queue = null, array $options = []) [$message, $correlationId] = $this->createMessage($payload, $attempts); - $this->channel->batch_basic_publish($message, $exchange, $destination); + $this->getChannel()->batch_basic_publish($message, $exchange, $destination); return $correlationId; } @@ -251,7 +220,7 @@ public function pop($queue = null) $job = $this->getJobClass(); /** @var AMQPMessage|null $message */ - if ($message = $this->channel->basic_get($queue)) { + if ($message = $this->getChannel()->basic_get($queue)) { return $this->currentJob = new $job( $this->container, $this, @@ -261,12 +230,12 @@ public function pop($queue = null) ); } } catch (AMQPProtocolChannelException $exception) { - // If there is not exchange or queue AMQP will throw exception with code 404 + // If there is no exchange or queue AMQP will throw exception with code 404 // We need to catch it and return null if ($exception->amqp_reply_code === 404) { // Because of the channel exception the channel was closed and removed. // We have to open a new channel. Because else the worker(s) are stuck in a loop, without processing. - $this->channel = $this->connection->channel(); + $this->channel = $this->getConnection()->channel(); return null; } @@ -292,6 +261,14 @@ public function getConnection(): AbstractConnection return $this->connection; } + public function setConnection(AbstractConnection $connection): RabbitMQQueue + { + $this->connection = $connection; + $this->channel = $connection->channel(); + + return $this; + } + public function getChannel(): AMQPChannel { return $this->channel; @@ -305,7 +282,7 @@ public function getChannel(): AMQPChannel */ public function getJobClass(): string { - $job = Arr::get($this->options, 'job', RabbitMQJob::class); + $job = $this->getConfig()->getAbstractJob(); throw_if( ! is_a($job, RabbitMQJob::class, true), @@ -323,12 +300,12 @@ public function getJobClass(): string */ public function getQueue($queue = null): string { - return $queue ?: $this->default; + return $queue ?: $this->getConfig()->getQueue(); } /** * Checks if the given exchange already present/defined in RabbitMQ. - * Returns false when when the exchange is missing. + * Returns false when the exchange is missing. * * * @throws AMQPProtocolChannelException @@ -341,7 +318,7 @@ public function isExchangeExists(string $exchange): bool try { // create a temporary channel, so the main channel will not be closed on exception - $channel = $this->connection->channel(); + $channel = $this->getConnection()->channel(); $channel->exchange_declare($exchange, '', true); $channel->close(); @@ -358,7 +335,7 @@ public function isExchangeExists(string $exchange): bool } /** - * Declare a exchange in rabbitMQ, when not already declared. + * Declare an exchange in rabbitMQ, when not already declared. */ public function declareExchange( string $name, @@ -371,7 +348,7 @@ public function declareExchange( return; } - $this->channel->exchange_declare( + $this->getChannel()->exchange_declare( $name, $type, false, @@ -384,7 +361,7 @@ public function declareExchange( } /** - * Delete a exchange from rabbitMQ, only when present in RabbitMQ. + * Delete an exchange from rabbitMQ, only when present in RabbitMQ. * * * @throws AMQPProtocolChannelException @@ -398,7 +375,7 @@ public function deleteExchange(string $name, bool $unused = false): void $idx = array_search($name, $this->exchanges); unset($this->exchanges[$idx]); - $this->channel->exchange_delete( + $this->getChannel()->exchange_delete( $name, $unused ); @@ -406,7 +383,7 @@ public function deleteExchange(string $name, bool $unused = false): void /** * Checks if the given queue already present/defined in RabbitMQ. - * Returns false when when the queue is missing. + * Returns false when the queue is missing. * * * @throws AMQPProtocolChannelException @@ -415,7 +392,7 @@ public function isQueueExists(string $name = null): bool { try { // create a temporary channel, so the main channel will not be closed on exception - $channel = $this->connection->channel(); + $channel = $this->getConnection()->channel(); $channel->queue_declare($this->getQueue($name), true); $channel->close(); @@ -442,7 +419,7 @@ public function declareQueue( return; } - $this->channel->queue_declare( + $this->getChannel()->queue_declare( $name, false, $durable, @@ -465,7 +442,7 @@ public function deleteQueue(string $name, bool $if_unused = false, bool $if_empt return; } - $this->channel->queue_delete($name, $if_unused, $if_empty); + $this->getChannel()->queue_delete($name, $if_unused, $if_empty); } /** @@ -481,7 +458,7 @@ public function bindQueue(string $queue, string $exchange, string $routingKey = return; } - $this->channel->queue_bind($queue, $exchange, $routingKey); + $this->getChannel()->queue_bind($queue, $exchange, $routingKey); } /** @@ -490,7 +467,7 @@ public function bindQueue(string $queue, string $exchange, string $routingKey = public function purge(string $queue = null): void { // create a temporary channel, so the main channel will not be closed on exception - $channel = $this->connection->channel(); + $channel = $this->getConnection()->channel(); $channel->queue_purge($this->getQueue($queue)); $channel->close(); } @@ -500,7 +477,7 @@ public function purge(string $queue = null): void */ public function ack(RabbitMQJob $job): void { - $this->channel->basic_ack($job->getRabbitMQMessage()->getDeliveryTag()); + $this->getChannel()->basic_ack($job->getRabbitMQMessage()->getDeliveryTag()); } /** @@ -508,14 +485,11 @@ public function ack(RabbitMQJob $job): void */ public function reject(RabbitMQJob $job, bool $requeue = false): void { - $this->channel->basic_reject($job->getRabbitMQMessage()->getDeliveryTag(), $requeue); + $this->getChannel()->basic_reject($job->getRabbitMQMessage()->getDeliveryTag(), $requeue); } /** * Create a AMQP message. - * - * - * @throws JsonException */ protected function createMessage($payload, int $attempts = 0): array { @@ -524,12 +498,12 @@ protected function createMessage($payload, int $attempts = 0): array 'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT, ]; - $currentPayload = json_decode($payload, true, 512); + $currentPayload = json_decode($payload, true); if ($correlationId = $currentPayload['id'] ?? null) { $properties['correlation_id'] = $correlationId; } - if ($this->isPrioritizeDelayed()) { + if ($this->getConfig()->isPrioritizeDelayed()) { $properties['priority'] = $attempts; } @@ -584,13 +558,13 @@ protected function getRandomId(): string */ public function close(): void { - if ($this->currentJob && ! $this->currentJob->isDeletedOrReleased()) { + if (! $this->currentJob->isDeletedOrReleased()) { $this->reject($this->currentJob, true); } try { $this->connection->close(); - } catch (ErrorException $exception) { + } catch (ErrorException) { // Ignore the exception } } @@ -606,16 +580,16 @@ protected function getQueueArguments(string $destination): array // Messages with a priority which is higher than the queue's maximum, are treated as if they were // published with the maximum priority. // Quorum queues does not support priority. - if ($this->isPrioritizeDelayed() && ! $this->isQuorum()) { - $arguments['x-max-priority'] = $this->getQueueMaxPriority(); + if ($this->getConfig()->isPrioritizeDelayed() && ! $this->getConfig()->isQuorum()) { + $arguments['x-max-priority'] = $this->getConfig()->getQueueMaxPriority(); } - if ($this->isRerouteFailed()) { + if ($this->getConfig()->isRerouteFailed()) { $arguments['x-dead-letter-exchange'] = $this->getFailedExchange() ?? ''; $arguments['x-dead-letter-routing-key'] = $this->getFailedRoutingKey($destination); } - if ($this->isQuorum()) { + if ($this->getConfig()->isQuorum()) { $arguments['x-queue-type'] = 'quorum'; } @@ -635,32 +609,12 @@ protected function getDelayQueueArguments(string $destination, int $ttl): array ]; } - /** - * Returns &true;, if delayed messages should be prioritized. - */ - protected function isPrioritizeDelayed(): bool - { - return (bool) (Arr::get($this->options, 'prioritize_delayed') ?: false); - } - - /** - * Returns a integer with a default of '2' for when using prioritization on delayed messages. - * If priority queues are desired, we recommend using between 1 and 10. - * Using more priority layers, will consume more CPU resources and would affect runtimes. - * - * @see https://www.rabbitmq.com/priority.html - */ - protected function getQueueMaxPriority(): int - { - return (int) (Arr::get($this->options, 'queue_max_priority') ?: 2); - } - /** * Get the exchange name, or &null; as default value. */ protected function getExchange(string $exchange = null): ?string { - return $exchange ?: Arr::get($this->options, 'exchange') ?: null; + return $exchange ?: $this->getConfig()->getExchange(); } /** @@ -669,7 +623,7 @@ protected function getExchange(string $exchange = null): ?string */ protected function getRoutingKey(string $destination): string { - return ltrim(sprintf(Arr::get($this->options, 'exchange_routing_key') ?: '%s', $destination), '.'); + return ltrim(sprintf($this->getConfig()->getExchangeRoutingKey(), $destination), '.'); } /** @@ -677,26 +631,7 @@ protected function getRoutingKey(string $destination): string */ protected function getExchangeType(?string $type = null): string { - return @constant(AMQPExchangeType::class.'::'.Str::upper($type ?: Arr::get( - $this->options, - 'exchange_type' - ) ?: 'direct')) ?: AMQPExchangeType::DIRECT; - } - - /** - * Returns &true;, if failed messages should be rerouted. - */ - protected function isRerouteFailed(): bool - { - return (bool) (Arr::get($this->options, 'reroute_failed') ?: false); - } - - /** - * Returns &true;, if declared queue must be quorum queue. - */ - protected function isQuorum(): bool - { - return (bool) (Arr::get($this->options, 'quorum') ?: false); + return @constant(AMQPExchangeType::class.'::'.Str::upper($type ?: $this->getConfig()->getExchangeType())) ?: AMQPExchangeType::DIRECT; } /** @@ -704,7 +639,7 @@ protected function isQuorum(): bool */ protected function getFailedExchange(string $exchange = null): ?string { - return $exchange ?: Arr::get($this->options, 'failed_exchange') ?: null; + return $exchange ?: $this->getConfig()->getFailedExchange(); } /** @@ -713,7 +648,7 @@ protected function getFailedExchange(string $exchange = null): ?string */ protected function getFailedRoutingKey(string $destination): string { - return ltrim(sprintf(Arr::get($this->options, 'failed_routing_key') ?: '%s.failed', $destination), '.'); + return ltrim(sprintf($this->getConfig()->getFailedRoutingKey(), $destination), '.'); } /** @@ -735,21 +670,17 @@ protected function isQueueDeclared(string $name): bool /** * Declare the destination when necessary. * - * @param string|null $exchangeType * * @throws AMQPProtocolChannelException */ - protected function declareDestination( - string $destination, - ?string $exchange = null, - string $exchangeType = AMQPExchangeType::DIRECT - ): void { - // When a exchange is provided and no exchange is present in RabbitMQ, create an exchange. + protected function declareDestination(string $destination, ?string $exchange = null, string $exchangeType = AMQPExchangeType::DIRECT): void + { + // When an exchange is provided and no exchange is present in RabbitMQ, create an exchange. if ($exchange && ! $this->isExchangeExists($exchange)) { $this->declareExchange($exchange, $exchangeType); } - // When a exchange is provided, just return. + // When an exchange is provided, just return. if ($exchange) { return; } @@ -777,4 +708,9 @@ protected function publishProperties($queue, array $options = []): array return [$destination, $exchange, $exchangeType, $attempts]; } + + public function getConfig(): QueueConfig + { + return $this->config; + } } diff --git a/tests/Functional/RabbitMQQueueTest.php b/tests/Functional/RabbitMQQueueTest.php index 1c03fe99..535e6f74 100644 --- a/tests/Functional/RabbitMQQueueTest.php +++ b/tests/Functional/RabbitMQQueueTest.php @@ -11,7 +11,6 @@ class RabbitMQQueueTest extends BaseTestCase { public function testConnection(): void { - /** @var $queue RabbitMQQueue */ $queue = $this->connection(); $this->assertInstanceOf(RabbitMQQueue::class, $queue); @@ -22,51 +21,47 @@ public function testConnection(): void $this->assertInstanceOf(RabbitMQQueue::class, $queue); } - public function testRerouteFailed(): void + public function testConfigRerouteFailed(): void { - /** @var $queue RabbitMQQueue */ - $queue = $this->connection(); - $this->assertFalse($this->callMethod($queue, 'isRerouteFailed')); + $config = $this->connection()->getConfig(); + $this->assertFalse($this->callMethod($config, 'isRerouteFailed')); - $queue = $this->connection('rabbitmq-with-options'); - $this->assertTrue($this->callMethod($queue, 'isRerouteFailed')); + $config = $this->connection('rabbitmq-with-options')->getConfig(); + $this->assertTrue($this->callMethod($config, 'isRerouteFailed')); - $queue = $this->connection('rabbitmq-with-options-empty'); - $this->assertFalse($this->callMethod($queue, 'isRerouteFailed')); + $config = $this->connection('rabbitmq-with-options-empty')->getConfig(); + $this->assertFalse($this->callMethod($config, 'isRerouteFailed')); } - public function testPrioritizeDelayed(): void + public function testConfigPrioritizeDelayed(): void { - /** @var $queue RabbitMQQueue */ - $queue = $this->connection(); - $this->assertFalse($this->callMethod($queue, 'isPrioritizeDelayed')); + $config = $this->connection()->getConfig(); + $this->assertFalse($this->callMethod($config, 'isPrioritizeDelayed')); - $queue = $this->connection('rabbitmq-with-options'); - $this->assertTrue($this->callMethod($queue, 'isPrioritizeDelayed')); + $config = $this->connection('rabbitmq-with-options')->getConfig(); + $this->assertTrue($this->callMethod($config, 'isPrioritizeDelayed')); - $queue = $this->connection('rabbitmq-with-options-empty'); - $this->assertFalse($this->callMethod($queue, 'isPrioritizeDelayed')); + $config = $this->connection('rabbitmq-with-options-empty')->getConfig(); + $this->assertFalse($this->callMethod($config, 'isPrioritizeDelayed')); } public function testQueueMaxPriority(): void { - /** @var $queue RabbitMQQueue */ - $queue = $this->connection(); - $this->assertIsInt($this->callMethod($queue, 'getQueueMaxPriority')); - $this->assertSame(2, $this->callMethod($queue, 'getQueueMaxPriority')); + $config = $this->connection()->getConfig(); + $this->assertIsInt($this->callMethod($config, 'getQueueMaxPriority')); + $this->assertSame(2, $this->callMethod($config, 'getQueueMaxPriority')); - $queue = $this->connection('rabbitmq-with-options'); - $this->assertIsInt($this->callMethod($queue, 'getQueueMaxPriority')); - $this->assertSame(20, $this->callMethod($queue, 'getQueueMaxPriority')); + $config = $this->connection('rabbitmq-with-options')->getConfig(); + $this->assertIsInt($this->callMethod($config, 'getQueueMaxPriority')); + $this->assertSame(20, $this->callMethod($config, 'getQueueMaxPriority')); - $queue = $this->connection('rabbitmq-with-options-empty'); - $this->assertIsInt($this->callMethod($queue, 'getQueueMaxPriority')); - $this->assertSame(2, $this->callMethod($queue, 'getQueueMaxPriority')); + $config = $this->connection('rabbitmq-with-options-empty')->getConfig(); + $this->assertIsInt($this->callMethod($config, 'getQueueMaxPriority')); + $this->assertSame(2, $this->callMethod($config, 'getQueueMaxPriority')); } - public function testExchangeType(): void + public function testConfigExchangeType(): void { - /** @var $queue RabbitMQQueue */ $queue = $this->connection(); $this->assertSame(AMQPExchangeType::DIRECT, $this->callMethod($queue, 'getExchangeType')); $this->assertSame(AMQPExchangeType::DIRECT, $this->callMethod($queue, 'getExchangeType', [''])); @@ -81,7 +76,6 @@ public function testExchangeType(): void public function testExchange(): void { - /** @var $queue RabbitMQQueue */ $queue = $this->connection(); $this->assertSame('test', $this->callMethod($queue, 'getExchange', ['test'])); $this->assertNull($this->callMethod($queue, 'getExchange', [''])); @@ -97,7 +91,6 @@ public function testExchange(): void public function testFailedExchange(): void { - /** @var $queue RabbitMQQueue */ $queue = $this->connection(); $this->assertSame('test', $this->callMethod($queue, 'getFailedExchange', ['test'])); $this->assertNull($this->callMethod($queue, 'getExchange', [''])); @@ -113,7 +106,6 @@ public function testFailedExchange(): void public function testRoutingKey(): void { - /** @var $queue RabbitMQQueue */ $queue = $this->connection(); $this->assertSame('test', $this->callMethod($queue, 'getRoutingKey', ['test'])); $this->assertSame('', $this->callMethod($queue, 'getRoutingKey', [''])); @@ -127,8 +119,8 @@ public function testRoutingKey(): void public function testFailedRoutingKey(): void { - /** @var $queue RabbitMQQueue */ $queue = $this->connection(); + $this->assertSame('test.failed', $this->callMethod($queue, 'getFailedRoutingKey', ['test'])); $this->assertSame('failed', $this->callMethod($queue, 'getFailedRoutingKey', [''])); @@ -139,25 +131,23 @@ public function testFailedRoutingKey(): void $this->assertSame('test.failed', $this->callMethod($queue, 'getFailedRoutingKey', ['test'])); } - public function testQuorum(): void + public function testConfigQuorum(): void { - /** @var $queue RabbitMQQueue */ - $queue = $this->connection(); - $this->assertFalse($this->callMethod($queue, 'isQuorum')); + $config = $this->connection()->getConfig(); + $this->assertFalse($this->callMethod($config, 'isQuorum')); - $queue = $this->connection('rabbitmq-with-options'); - $this->assertFalse($this->callMethod($queue, 'isQuorum')); + $config = $this->connection('rabbitmq-with-options')->getConfig(); + $this->assertFalse($this->callMethod($config, 'isQuorum')); - $queue = $this->connection('rabbitmq-with-quorum-options'); - $this->assertTrue($this->callMethod($queue, 'isQuorum')); + $config = $this->connection('rabbitmq-with-options-empty')->getConfig(); + $this->assertFalse($this->callMethod($config, 'isQuorum')); - $queue = $this->connection('rabbitmq-with-options-empty'); - $this->assertFalse($this->callMethod($queue, 'isQuorum')); + $config = $this->connection('rabbitmq-with-quorum-options')->getConfig(); + $this->assertTrue($this->callMethod($config, 'isQuorum')); } public function testDeclareDeleteExchange(): void { - /** @var $queue RabbitMQQueue */ $queue = $this->connection(); $name = Str::random(); @@ -173,7 +163,6 @@ public function testDeclareDeleteExchange(): void public function testDeclareDeleteQueue(): void { - /** @var $queue RabbitMQQueue */ $queue = $this->connection(); $name = Str::random(); @@ -191,7 +180,6 @@ public function testQueueArguments(): void { $name = Str::random(); - /** @var $queue RabbitMQQueue */ $queue = $this->connection(); $actual = $this->callMethod($queue, 'getQueueArguments', [$name]); $expected = []; @@ -233,7 +221,6 @@ public function testDelayQueueArguments(): void $name = Str::random(); $ttl = 12000; - /** @var $queue RabbitMQQueue */ $queue = $this->connection(); $actual = $this->callMethod($queue, 'getDelayQueueArguments', [$name, $ttl]); $expected = [ From 3a32d71a9b8fc5ad2934c2b3a8ff71d3d636c33c Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Thu, 2 Mar 2023 19:51:48 +0100 Subject: [PATCH 034/150] fixed: static factory call --- src/Queue/Connectors/RabbitMQConnector.php | 5 +---- src/Queue/QueueFactory.php | 17 ++++++----------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/Queue/Connectors/RabbitMQConnector.php b/src/Queue/Connectors/RabbitMQConnector.php index 8d8498b4..53751c8b 100644 --- a/src/Queue/Connectors/RabbitMQConnector.php +++ b/src/Queue/Connectors/RabbitMQConnector.php @@ -20,12 +20,9 @@ class RabbitMQConnector implements ConnectorInterface { private Dispatcher $dispatcher; - private QueueFactory $queue; - public function __construct(Dispatcher $dispatcher) { $this->dispatcher = $dispatcher; - $this->queue = new QueueFactory(); } /** @@ -40,7 +37,7 @@ public function connect(array $config): Queue // Todo Create ConnectionFactory removing all deprecated dependicies $connection = $this->createConnection(Arr::except($config, 'options.queue')); - $queue = $this->queue->make($config)->setConnection($connection); + $queue = QueueFactory::make($config)->setConnection($connection); if ($queue instanceof HorizonRabbitMQQueue) { $this->dispatcher->listen(JobFailed::class, RabbitMQFailedEvent::class); diff --git a/src/Queue/QueueFactory.php b/src/Queue/QueueFactory.php index ccbfd51d..2595d8a4 100644 --- a/src/Queue/QueueFactory.php +++ b/src/Queue/QueueFactory.php @@ -7,31 +7,26 @@ final class QueueFactory { - protected $queue; - - /** - * Create a Queue - */ - public function make(array $config = []): RabbitMQQueue + public static function make(array $config = []): RabbitMQQueue { - $queueConfig = $this->createQueueConfig($config); + $queueConfig = self::createQueueConfig($config); $worker = Arr::get($config, 'worker', 'default'); if (strtolower($worker) == 'default') { - return $this->queue = new RabbitMQQueue($queueConfig); + return new RabbitMQQueue($queueConfig); } if (strtolower($worker) == 'horizon') { - return $this->queue = new HorizonRabbitMQQueue($queueConfig); + return new HorizonRabbitMQQueue($queueConfig); } - return $this->queue = new $worker($queueConfig); + return new $worker($queueConfig); } /** * Create a config object from config array */ - private function createQueueConfig(array $config = []): QueueConfig + private static function createQueueConfig(array $config = []): QueueConfig { return tap(new QueueConfig(), function (QueueConfig $queueConfig) use ($config) { if (! empty($queue = Arr::get($config, 'queue'))) { From 019a41138c6c869c8e31b1a211294e5f4bc53e5d Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Thu, 2 Mar 2023 21:39:04 +0100 Subject: [PATCH 035/150] fixed: - reverted config tests - private config getter --- src/Queue/RabbitMQQueue.php | 2 +- tests/Functional/RabbitMQQueueTest.php | 58 +++++++++++++------------- tests/Functional/TestCase.php | 20 ++++++++- 3 files changed, 49 insertions(+), 31 deletions(-) diff --git a/src/Queue/RabbitMQQueue.php b/src/Queue/RabbitMQQueue.php index 59d98f3a..22cced8b 100644 --- a/src/Queue/RabbitMQQueue.php +++ b/src/Queue/RabbitMQQueue.php @@ -709,7 +709,7 @@ protected function publishProperties($queue, array $options = []): array return [$destination, $exchange, $exchangeType, $attempts]; } - public function getConfig(): QueueConfig + private function getConfig(): QueueConfig { return $this->config; } diff --git a/tests/Functional/RabbitMQQueueTest.php b/tests/Functional/RabbitMQQueueTest.php index 535e6f74..5a50342b 100644 --- a/tests/Functional/RabbitMQQueueTest.php +++ b/tests/Functional/RabbitMQQueueTest.php @@ -23,41 +23,41 @@ public function testConnection(): void public function testConfigRerouteFailed(): void { - $config = $this->connection()->getConfig(); - $this->assertFalse($this->callMethod($config, 'isRerouteFailed')); + $queue = $this->connection(); + $this->assertFalse($this->callProperty($queue, 'config')->isRerouteFailed()); - $config = $this->connection('rabbitmq-with-options')->getConfig(); - $this->assertTrue($this->callMethod($config, 'isRerouteFailed')); + $queue = $this->connection('rabbitmq-with-options'); + $this->assertTrue($this->callProperty($queue, 'config')->isRerouteFailed()); - $config = $this->connection('rabbitmq-with-options-empty')->getConfig(); - $this->assertFalse($this->callMethod($config, 'isRerouteFailed')); + $queue = $this->connection('rabbitmq-with-options-empty'); + $this->assertFalse($this->callProperty($queue, 'config')->isRerouteFailed()); } public function testConfigPrioritizeDelayed(): void { - $config = $this->connection()->getConfig(); - $this->assertFalse($this->callMethod($config, 'isPrioritizeDelayed')); + $queue = $this->connection(); + $this->assertFalse($this->callProperty($queue, 'config')->isPrioritizeDelayed()); - $config = $this->connection('rabbitmq-with-options')->getConfig(); - $this->assertTrue($this->callMethod($config, 'isPrioritizeDelayed')); + $queue = $this->connection('rabbitmq-with-options'); + $this->assertTrue($this->callProperty($queue, 'config')->isPrioritizeDelayed()); - $config = $this->connection('rabbitmq-with-options-empty')->getConfig(); - $this->assertFalse($this->callMethod($config, 'isPrioritizeDelayed')); + $queue = $this->connection('rabbitmq-with-options-empty'); + $this->assertFalse($this->callProperty($queue, 'config')->isPrioritizeDelayed()); } public function testQueueMaxPriority(): void { - $config = $this->connection()->getConfig(); - $this->assertIsInt($this->callMethod($config, 'getQueueMaxPriority')); - $this->assertSame(2, $this->callMethod($config, 'getQueueMaxPriority')); + $queue = $this->connection(); + $this->assertIsInt($this->callProperty($queue, 'config')->getQueueMaxPriority()); + $this->assertSame(2, $this->callProperty($queue, 'config')->getQueueMaxPriority()); - $config = $this->connection('rabbitmq-with-options')->getConfig(); - $this->assertIsInt($this->callMethod($config, 'getQueueMaxPriority')); - $this->assertSame(20, $this->callMethod($config, 'getQueueMaxPriority')); + $queue = $this->connection('rabbitmq-with-options'); + $this->assertIsInt($this->callProperty($queue, 'config')->getQueueMaxPriority()); + $this->assertSame(20, $this->callProperty($queue, 'config')->getQueueMaxPriority()); - $config = $this->connection('rabbitmq-with-options-empty')->getConfig(); - $this->assertIsInt($this->callMethod($config, 'getQueueMaxPriority')); - $this->assertSame(2, $this->callMethod($config, 'getQueueMaxPriority')); + $queue = $this->connection('rabbitmq-with-options-empty'); + $this->assertIsInt($this->callProperty($queue, 'config')->getQueueMaxPriority()); + $this->assertSame(2, $this->callProperty($queue, 'config')->getQueueMaxPriority()); } public function testConfigExchangeType(): void @@ -133,17 +133,17 @@ public function testFailedRoutingKey(): void public function testConfigQuorum(): void { - $config = $this->connection()->getConfig(); - $this->assertFalse($this->callMethod($config, 'isQuorum')); + $queue = $this->connection(); + $this->assertFalse($this->callProperty($queue, 'config')->isQuorum()); - $config = $this->connection('rabbitmq-with-options')->getConfig(); - $this->assertFalse($this->callMethod($config, 'isQuorum')); + $queue = $this->connection('rabbitmq-with-options'); + $this->assertFalse($this->callProperty($queue, 'config')->isQuorum()); - $config = $this->connection('rabbitmq-with-options-empty')->getConfig(); - $this->assertFalse($this->callMethod($config, 'isQuorum')); + $queue = $this->connection('rabbitmq-with-options-empty'); + $this->assertFalse($this->callProperty($queue, 'config')->isQuorum()); - $config = $this->connection('rabbitmq-with-quorum-options')->getConfig(); - $this->assertTrue($this->callMethod($config, 'isQuorum')); + $queue = $this->connection('rabbitmq-with-quorum-options'); + $this->assertTrue($this->callProperty($queue, 'config')->isQuorum()); } public function testDeclareDeleteExchange(): void diff --git a/tests/Functional/TestCase.php b/tests/Functional/TestCase.php index 01b3c069..1d3069f1 100644 --- a/tests/Functional/TestCase.php +++ b/tests/Functional/TestCase.php @@ -165,7 +165,7 @@ protected function getEnvironmentSetUp($app): void * * @throws Exception */ - protected function callMethod($object, string $method, array $parameters = []) + protected function callMethod($object, string $method, array $parameters = []): mixed { try { $className = get_class($object); @@ -179,4 +179,22 @@ protected function callMethod($object, string $method, array $parameters = []) return $method->invokeArgs($object, $parameters); } + + /** + * @throws Exception + */ + protected function callProperty($object, string $property): mixed + { + try { + $className = get_class($object); + $reflection = new ReflectionClass($className); + } catch (ReflectionException $e) { + throw new Exception($e->getMessage()); + } + + $property = $reflection->getProperty($property); + $property->setAccessible(true); + + return $property->getValue($object); + } } From aee2a4241e187086ae622a9058b8a432f6d6b45d Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Fri, 3 Mar 2023 10:58:25 +0100 Subject: [PATCH 036/150] fixed: - phpdoc tags --- tests/Functional/TestCase.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/Functional/TestCase.php b/tests/Functional/TestCase.php index 1d3069f1..5ffa54d9 100644 --- a/tests/Functional/TestCase.php +++ b/tests/Functional/TestCase.php @@ -161,8 +161,6 @@ protected function getEnvironmentSetUp($app): void } /** - * @return mixed - * * @throws Exception */ protected function callMethod($object, string $method, array $parameters = []): mixed From 3cee3ffd6d5f596d799152e4aa466bd91c5c09f9 Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Thu, 9 Mar 2023 18:50:14 +0100 Subject: [PATCH 037/150] added: - factory for making a connection. - factory for creating a config object. - test lazy stream connection. fixed: - tests removed: - unnecessary methods --- config/rabbitmq.php | 10 +- src/Queue/Connection/ConfigFactory.php | 93 +++++++++ src/Queue/Connection/ConnectionFactory.php | 224 +++++++++++++++++++++ src/Queue/Connectors/RabbitMQConnector.php | 47 +---- tests/Feature/ConnectorTest.php | 43 ++++ tests/Feature/QueueTest.php | 4 +- tests/Functional/TestCase.php | 9 +- 7 files changed, 369 insertions(+), 61 deletions(-) create mode 100644 src/Queue/Connection/ConfigFactory.php create mode 100644 src/Queue/Connection/ConnectionFactory.php diff --git a/config/rabbitmq.php b/config/rabbitmq.php index 900e3b74..4c102ce8 100644 --- a/config/rabbitmq.php +++ b/config/rabbitmq.php @@ -9,7 +9,7 @@ 'driver' => 'rabbitmq', 'queue' => env('RABBITMQ_QUEUE', 'default'), - 'connection' => PhpAmqpLib\Connection\AMQPLazyConnection::class, + 'connection' => 'default', 'hosts' => [ [ @@ -22,14 +22,6 @@ ], 'options' => [ - 'ssl_options' => [ - 'cafile' => env('RABBITMQ_SSL_CAFILE', null), - 'local_cert' => env('RABBITMQ_SSL_LOCALCERT', null), - 'local_key' => env('RABBITMQ_SSL_LOCALKEY', null), - 'verify_peer' => env('RABBITMQ_SSL_VERIFY_PEER', true), - 'passphrase' => env('RABBITMQ_SSL_PASSPHRASE', null), - ], - 'queue' => [], ], /* diff --git a/src/Queue/Connection/ConfigFactory.php b/src/Queue/Connection/ConfigFactory.php new file mode 100644 index 00000000..3e5e0c14 --- /dev/null +++ b/src/Queue/Connection/ConfigFactory.php @@ -0,0 +1,93 @@ +setIsLazy(! in_array( + Arr::get($config, 'lazy') ?? true, + [false, 0, '0', 'false'], + true) + ); + + // Set the connection to unsecure by default + $connectionConfig->setIsSecure(in_array( + Arr::get($config, 'secure'), + [true, 1, '1', 'true'], + true) + ); + + if ($connectionConfig->isSecure()) { + self::sllOptionsFromConfig($connectionConfig, $config); + } + + self::hostFromConfig($connectionConfig, $config); + self::heartbeatFromConfig($connectionConfig, $config); + }); + } + + protected static function hostFromConfig(AMQPConnectionConfig $connectionConfig, array $config): void + { + $hostConfig = Arr::first(Arr::shuffle(Arr::get($config, self::CONFIG_HOSTS, [])), null, []); + + if ($location = Arr::get($hostConfig, 'host')) { + $connectionConfig->setHost($location); + } + if ($port = Arr::get($hostConfig, 'port')) { + $connectionConfig->setPort($port); + } + if ($vhost = Arr::get($hostConfig, 'vhost')) { + $connectionConfig->setVhost($vhost); + } + if ($user = Arr::get($hostConfig, 'user')) { + $connectionConfig->setUser($user); + } + if ($password = Arr::get($hostConfig, 'password')) { + $connectionConfig->setPassword($password); + } + } + + protected static function sllOptionsFromConfig(AMQPConnectionConfig $connectionConfig, array $config): void + { + $sslConfig = Arr::get($config, self::CONFIG_OPTIONS.'.ssl_options', []); + + if ($caFile = Arr::get($sslConfig, 'cafile')) { + $connectionConfig->setSslCaCert($caFile); + } + if ($cert = Arr::get($sslConfig, 'local_cert')) { + $connectionConfig->setSslCert($cert); + } + if ($key = Arr::get($sslConfig, 'local_key')) { + $connectionConfig->setSslKey($key); + } + if ($verifyPeer = Arr::get($sslConfig, 'verify_peer')) { + $connectionConfig->setSslVerify($verifyPeer); + } + if ($passphrase = Arr::get($sslConfig, 'passphrase')) { + $connectionConfig->setSslPassPhrase($passphrase); + } + } + + protected static function heartbeatFromConfig(AMQPConnectionConfig $connectionConfig, array $config): void + { + $heartbeat = Arr::get($config, self::CONFIG_OPTIONS.'.heartbeat'); + + if (! empty($heartbeat) && is_numeric($heartbeat) && 0 < (int) $heartbeat) { + $connectionConfig->setHeartbeat($heartbeat); + } + } +} diff --git a/src/Queue/Connection/ConnectionFactory.php b/src/Queue/Connection/ConnectionFactory.php new file mode 100644 index 00000000..3b5c0fe1 --- /dev/null +++ b/src/Queue/Connection/ConnectionFactory.php @@ -0,0 +1,224 @@ +getIoType() === AMQPConnectionConfig::IO_TYPE_SOCKET) { + return self::createSocketConnection($connection, $config); + } + + return self::createStreamConnection($connection, $config); + } + + private static function createSocketConnection($connection, AMQPConnectionConfig $config): AMQPSocketConnection + { + self::assertSocketConnection($connection, $config); + + return new $connection( + $config->getHost(), + $config->getPort(), + $config->getUser(), + $config->getPassword(), + $config->getVhost(), + $config->isInsist(), + $config->getLoginMethod(), + $config->getLoginResponse(), + $config->getLocale(), + $config->getReadTimeout(), + $config->isKeepalive(), + $config->getWriteTimeout(), + $config->getHeartbeat(), + $config->getChannelRPCTimeout(), + $config + ); + } + + private static function createStreamConnection($connection, AMQPConnectionConfig $config): AMQPStreamConnection + { + self::assertStreamConnection($connection); + + if ($config->isSecure()) { + self::assertSSLConnection($connection); + + return new $connection( + $config->getHost(), + $config->getPort(), + $config->getUser(), + $config->getPassword(), + $config->getVhost(), + self::getSslOptions($config), + [ + 'insist' => $config->isInsist(), + 'login_method' => $config->getLoginMethod(), + 'login_response' => $config->getLoginResponse(), + 'locale' => $config->getLocale(), + 'connection_timeout' => $config->getConnectionTimeout(), + 'read_write_timeout' => self::getReadWriteTimeout($config), + 'keepalive' => $config->isKeepalive(), + 'heartbeat' => $config->getHeartbeat(), + ], + $config->getNetworkProtocol(), + $config + ); + } + + return new $connection( + $config->getHost(), + $config->getPort(), + $config->getUser(), + $config->getPassword(), + $config->getVhost(), + $config->isInsist(), + $config->getLoginMethod(), + $config->getLoginResponse(), + $config->getLocale(), + $config->getConnectionTimeout(), + self::getReadWriteTimeout($config), + $config->getStreamContext(), + $config->isKeepalive(), + $config->getHeartbeat(), + $config->getChannelRPCTimeout(), + $config->getNetworkProtocol(), + $config + ); + } + + protected static function getReadWriteTimeout(AMQPConnectionConfig $config): float + { + return min($config->getReadTimeout(), $config->getWriteTimeout()); + } + + private static function getSslOptions(AMQPConnectionConfig $config): array + { + return array_filter([ + 'cafile' => $config->getSslCaCert(), + 'capath' => $config->getSslCaPath(), + 'local_cert' => $config->getSslCert(), + 'local_pk' => $config->getSslKey(), + 'verify_peer' => $config->getSslVerify(), + 'verify_peer_name' => $config->getSslVerifyName(), + 'passphrase' => $config->getSslPassPhrase(), + 'ciphers' => $config->getSslCiphers(), + 'security_level' => $config->getSslSecurityLevel(), + ], static function ($value) { + return null !== $value; + }); + } + + private static function assertConnectionFromConfig(string $connection): void + { + if ($connection !== self::CONNECTION_TYPE_DEFAULT && ! is_subclass_of($connection, self::CONNECTION_TYPE_EXTENDED)) { + throw new AMQPLogicException(sprintf('The config property \'%s\' must contain \'%s\' or must extend: %s', self::CONFIG_CONNECTION, self::CONNECTION_TYPE_DEFAULT, class_basename(self::CONNECTION_TYPE_EXTENDED))); + } + } + + private static function assertSocketConnection($connection, AMQPConnectionConfig $config): void + { + self::assertExtendedOf($connection, self::CONNECTION_SUB_TYPE_SOCKET); + + if ($config->isSecure()) { + throw new AMQPLogicException('The socket connection implementation does not support secure connections.'); + } + } + + private static function assertStreamConnection($connection): void + { + self::assertExtendedOf($connection, self::CONNECTION_SUB_TYPE_STREAM); + } + + private static function assertSSLConnection($connection) + { + self::assertExtendedOf($connection, self::CONNECTION_SUB_TYPE_SSL); + } + + private static function assertExtendedOf($connection, string $abstract): void + { + if (! is_subclass_of($connection, $abstract)) { + throw new AMQPLogicException(sprintf('The connection must extend: %s', class_basename($abstract))); + } + } + + /** + * @return mixed + * + * @throws Exception + * + * @deprecated This is the fallback method, update your config asap. (example: connection => 'default') + */ + private static function _createLazyConnection($connection, array $config): AbstractConnection + { + return $connection::create_connection( + Arr::shuffle(Arr::get($config, ConfigFactory::CONFIG_HOSTS, [])), + Arr::add(Arr::get($config, 'options', []), 'heartbeat', 0) + ); + } +} diff --git a/src/Queue/Connectors/RabbitMQConnector.php b/src/Queue/Connectors/RabbitMQConnector.php index 53751c8b..97c964c1 100644 --- a/src/Queue/Connectors/RabbitMQConnector.php +++ b/src/Queue/Connectors/RabbitMQConnector.php @@ -8,11 +8,9 @@ use Illuminate\Queue\Connectors\ConnectorInterface; use Illuminate\Queue\Events\JobFailed; use Illuminate\Queue\Events\WorkerStopping; -use Illuminate\Support\Arr; -use PhpAmqpLib\Connection\AbstractConnection; -use PhpAmqpLib\Connection\AMQPLazyConnection; use VladimirYuldashev\LaravelQueueRabbitMQ\Horizon\Listeners\RabbitMQFailedEvent; use VladimirYuldashev\LaravelQueueRabbitMQ\Horizon\RabbitMQQueue as HorizonRabbitMQQueue; +use VladimirYuldashev\LaravelQueueRabbitMQ\Queue\Connection\ConnectionFactory; use VladimirYuldashev\LaravelQueueRabbitMQ\Queue\QueueFactory; use VladimirYuldashev\LaravelQueueRabbitMQ\Queue\RabbitMQQueue; @@ -34,8 +32,7 @@ public function __construct(Dispatcher $dispatcher) */ public function connect(array $config): Queue { - // Todo Create ConnectionFactory removing all deprecated dependicies - $connection = $this->createConnection(Arr::except($config, 'options.queue')); + $connection = ConnectionFactory::make($config); $queue = QueueFactory::make($config)->setConnection($connection); @@ -49,44 +46,4 @@ public function connect(array $config): Queue return $queue; } - - /** - * @throws Exception - */ - protected function createConnection(array $config): AbstractConnection - { - /** @var AbstractConnection $connection */ - $connection = Arr::get($config, 'connection', AMQPLazyConnection::class); - - // disable heartbeat when not configured, so long-running tasks will not fail - $config = Arr::add($config, 'options.heartbeat', 0); - - return $connection::create_connection( - Arr::shuffle(Arr::get($config, 'hosts', [])), - $this->filter(Arr::get($config, 'options', [])) - ); - } - - /** - * Recursively filter only null values. - */ - private function filter(array $array): array - { - foreach ($array as $index => &$value) { - if (is_array($value)) { - $value = $this->filter($value); - - continue; - } - - // If the value is null then remove it. - if ($value === null) { - unset($array[$index]); - - continue; - } - } - - return $array; - } } diff --git a/tests/Feature/ConnectorTest.php b/tests/Feature/ConnectorTest.php index 499018e9..00cf5d6e 100644 --- a/tests/Feature/ConnectorTest.php +++ b/tests/Feature/ConnectorTest.php @@ -5,6 +5,7 @@ use Illuminate\Queue\QueueManager; use PhpAmqpLib\Connection\AMQPLazyConnection; use PhpAmqpLib\Connection\AMQPSSLConnection; +use PhpAmqpLib\Connection\AMQPStreamConnection; use VladimirYuldashev\LaravelQueueRabbitMQ\Queue\RabbitMQQueue; class ConnectorTest extends \VladimirYuldashev\LaravelQueueRabbitMQ\Tests\TestCase @@ -51,6 +52,48 @@ public function testLazyConnection(): void $this->assertTrue($connection->getChannel()->is_open()); } + public function testLazyStreamConnection(): void + { + $this->app['config']->set('queue.connections.rabbitmq', [ + 'driver' => 'rabbitmq', + 'queue' => env('RABBITMQ_QUEUE', 'default'), + 'connection' => 'default', + + 'hosts' => [ + [ + 'host' => getenv('HOST'), + 'port' => getenv('PORT'), + 'user' => 'guest', + 'password' => 'guest', + 'vhost' => '/', + ], + ], + + 'options' => [ + 'ssl_options' => [ + 'cafile' => env('RABBITMQ_SSL_CAFILE', null), + 'local_cert' => env('RABBITMQ_SSL_LOCALCERT', null), + 'local_key' => env('RABBITMQ_SSL_LOCALKEY', null), + 'verify_peer' => env('RABBITMQ_SSL_VERIFY_PEER', true), + 'passphrase' => env('RABBITMQ_SSL_PASSPHRASE', null), + ], + ], + + 'worker' => env('RABBITMQ_WORKER', 'default'), + ]); + + /** @var QueueManager $queue */ + $queue = $this->app['queue']; + + /** @var RabbitMQQueue $connection */ + $connection = $queue->connection('rabbitmq'); + + $this->assertInstanceOf(RabbitMQQueue::class, $connection); + $this->assertInstanceOf(AMQPStreamConnection::class, $connection->getConnection()); + $this->assertTrue($connection->getConnection()->isConnected()); + $this->assertTrue($connection->getChannel()->is_open()); + } + public function testSslConnection(): void { $this->markTestSkipped(); diff --git a/tests/Feature/QueueTest.php b/tests/Feature/QueueTest.php index 15b8acbb..3258b7f2 100644 --- a/tests/Feature/QueueTest.php +++ b/tests/Feature/QueueTest.php @@ -2,12 +2,12 @@ namespace VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Feature; -use PhpAmqpLib\Connection\AMQPLazyConnection; +use PhpAmqpLib\Connection\AMQPStreamConnection; class QueueTest extends TestCase { public function testConnection(): void { - $this->assertInstanceOf(AMQPLazyConnection::class, $this->connection()->getChannel()->getConnection()); + $this->assertInstanceOf(AMQPStreamConnection::class, $this->connection()->getChannel()->getConnection()); } } diff --git a/tests/Functional/TestCase.php b/tests/Functional/TestCase.php index 5ffa54d9..4edc8853 100644 --- a/tests/Functional/TestCase.php +++ b/tests/Functional/TestCase.php @@ -3,7 +3,6 @@ namespace VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Functional; use Exception; -use PhpAmqpLib\Connection\AMQPLazyConnection; use ReflectionClass; use ReflectionException; use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\TestCase as BaseTestCase; @@ -16,7 +15,7 @@ protected function getEnvironmentSetUp($app): void $app['config']->set('queue.connections.rabbitmq', [ 'driver' => 'rabbitmq', 'queue' => 'order', - 'connection' => AMQPLazyConnection::class, + 'connection' => 'default', 'hosts' => [ [ @@ -44,7 +43,7 @@ protected function getEnvironmentSetUp($app): void $app['config']->set('queue.connections.rabbitmq-with-options', [ 'driver' => 'rabbitmq', 'queue' => 'order', - 'connection' => AMQPLazyConnection::class, + 'connection' => 'default', 'hosts' => [ [ @@ -83,7 +82,7 @@ protected function getEnvironmentSetUp($app): void $app['config']->set('queue.connections.rabbitmq-with-options-empty', [ 'driver' => 'rabbitmq', 'queue' => 'order', - 'connection' => AMQPLazyConnection::class, + 'connection' => 'default', 'hosts' => [ [ @@ -123,7 +122,7 @@ protected function getEnvironmentSetUp($app): void $app['config']->set('queue.connections.rabbitmq-with-quorum-options', [ 'driver' => 'rabbitmq', 'queue' => 'order', - 'connection' => AMQPLazyConnection::class, + 'connection' => 'default', 'hosts' => [ [ From 3edec270c6fd5e22df42c5f51a0115276f41f579 Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Thu, 9 Mar 2023 18:50:47 +0100 Subject: [PATCH 038/150] documented connection options and config --- README.md | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 24c25862..d425e77b 100644 --- a/README.md +++ b/README.md @@ -254,9 +254,83 @@ class RabbitMQJob extends BaseJob } ``` +### SSL Secure + +When u need a secure connection to rabbitMQ server(s). Then this is posible by settitng extra config options. + +```php +'connections' => [ + // ... + + 'rabbitmq' => [ + // ... + + 'secure' = > true, + 'options' => [ + // ... + + 'ssl_options' => [ + 'cafile' => env('RABBITMQ_SSL_CAFILE', null), + 'local_cert' => env('RABBITMQ_SSL_LOCALCERT', null), + 'local_key' => env('RABBITMQ_SSL_LOCALKEY', null), + 'verify_peer' => env('RABBITMQ_SSL_VERIFY_PEER', true), + 'passphrase' => env('RABBITMQ_SSL_PASSPHRASE', null), + ], + ], + ], + + // ... +], +``` + +### Lazy Connection + +By default, your connection will be created as a lazy connection. +If for some reason you dont want the connection lazy you can turn it off by setting the following config. + +```php +'connections' => [ + // ... + + 'rabbitmq' => [ + // ... + + 'lazy' = > false, + ], + + // ... +], +``` + +### Heartbeat + +By default, your connection will be created with a heartbeat setting of `0`. +You can alter the heartbeat settings by changing the config. + +```php + +'connections' => [ + // ... + + 'rabbitmq' => [ + // ... + + 'secure' = > true, + 'options' => [ + // ... + + 'heartbeat' => 10, + ], + ], + + // ... +], +``` + ## Laravel Usage -Once you completed the configuration you can use the Laravel Queue API. If you used other queue drivers you do not need to +Once you completed the configuration you can use the Laravel Queue API. If you used other queue drivers you do not need +to change anything else. If you do not know how to use the Queue API, please refer to the official Laravel documentation: http://laravel.com/docs/queues From 6dd098f4c9edabd177322a553bf8801e646a4f55 Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Thu, 9 Mar 2023 19:03:12 +0100 Subject: [PATCH 039/150] small code style fix --- src/Queue/Connection/ConnectionFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Queue/Connection/ConnectionFactory.php b/src/Queue/Connection/ConnectionFactory.php index 3b5c0fe1..d9879dbe 100644 --- a/src/Queue/Connection/ConnectionFactory.php +++ b/src/Queue/Connection/ConnectionFactory.php @@ -195,7 +195,7 @@ private static function assertStreamConnection($connection): void self::assertExtendedOf($connection, self::CONNECTION_SUB_TYPE_STREAM); } - private static function assertSSLConnection($connection) + private static function assertSSLConnection($connection): void { self::assertExtendedOf($connection, self::CONNECTION_SUB_TYPE_SSL); } From 92a1ef44ad2cbf88a31689cd644eb81dd7b63734 Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Thu, 9 Mar 2023 19:24:55 +0100 Subject: [PATCH 040/150] update php-amqplib --- composer.json | 112 +++++++++++++++++++++++++------------------------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/composer.json b/composer.json index 5461314d..2238a6b3 100644 --- a/composer.json +++ b/composer.json @@ -1,59 +1,59 @@ { - "name": "vladimir-yuldashev/laravel-queue-rabbitmq", - "description": "RabbitMQ driver for Laravel Queue. Supports Laravel Horizon.", - "license": "MIT", - "authors": [ - { - "name": "Vladimir Yuldashev", - "email": "misterio92@gmail.com" - } - ], - "require": { - "php": "^8.0", - "ext-json": "*", - "illuminate/queue": "^9.0|^10.0", - "php-amqplib/php-amqplib": "^3.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "mockery/mockery": "^1.0", - "laravel/horizon": "^5.0", - "orchestra/testbench": "^7.0|^8.0", - "laravel/pint": "^1.2", - "laravel/framework": "^9.0|^10.0" - }, - "autoload": { - "psr-4": { - "VladimirYuldashev\\LaravelQueueRabbitMQ\\": "src/" - } - }, - "autoload-dev": { - "psr-4": { - "VladimirYuldashev\\LaravelQueueRabbitMQ\\Tests\\": "tests/" - } - }, - "extra": { - "branch-alias": { - "dev-master": "13.0-dev" - }, - "laravel": { - "providers": [ - "VladimirYuldashev\\LaravelQueueRabbitMQ\\LaravelQueueRabbitMQServiceProvider" - ] - } - }, - "suggest": { - "ext-pcntl": "Required to use all features of the queue consumer." - }, - "scripts": { - "test": [ - "@test:style", - "@test:unit" + "name": "vladimir-yuldashev/laravel-queue-rabbitmq", + "description": "RabbitMQ driver for Laravel Queue. Supports Laravel Horizon.", + "license": "MIT", + "authors": [ + { + "name": "Vladimir Yuldashev", + "email": "misterio92@gmail.com" + } ], - "test:style": "@php vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php --allow-risky=yes --dry-run --diff --verbose", - "test:unit": "@php vendor/bin/phpunit", - "fix:style": "@php vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php --allow-risky=yes --diff --verbose" - }, - "minimum-stability": "dev", - "prefer-stable": true + "require": { + "php": "^8.0", + "ext-json": "*", + "illuminate/queue": "^9.0|^10.0", + "php-amqplib/php-amqplib": "^v3.5" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "mockery/mockery": "^1.0", + "laravel/horizon": "^5.0", + "orchestra/testbench": "^7.0|^8.0", + "laravel/pint": "^1.2", + "laravel/framework": "^9.0|^10.0" + }, + "autoload": { + "psr-4": { + "VladimirYuldashev\\LaravelQueueRabbitMQ\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "VladimirYuldashev\\LaravelQueueRabbitMQ\\Tests\\": "tests/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "13.0-dev" + }, + "laravel": { + "providers": [ + "VladimirYuldashev\\LaravelQueueRabbitMQ\\LaravelQueueRabbitMQServiceProvider" + ] + } + }, + "suggest": { + "ext-pcntl": "Required to use all features of the queue consumer." + }, + "scripts": { + "test": [ + "@test:style", + "@test:unit" + ], + "test:style": "@php vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php --allow-risky=yes --dry-run --diff --verbose", + "test:unit": "@php vendor/bin/phpunit", + "fix:style": "@php vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php --allow-risky=yes --diff --verbose" + }, + "minimum-stability": "dev", + "prefer-stable": true } From 222ddb404c983a8a0ba8565a9e03a4622bcec9f2 Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Sat, 11 Mar 2023 21:40:26 +0100 Subject: [PATCH 041/150] update php-amqplib - reverted to minimal requirement update --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 2238a6b3..c29cd7d2 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ "php": "^8.0", "ext-json": "*", "illuminate/queue": "^9.0|^10.0", - "php-amqplib/php-amqplib": "^v3.5" + "php-amqplib/php-amqplib": "^v3.2.0" }, "require-dev": { "phpunit/phpunit": "^9.3", From 502bb75e47712eadb9017aeede0a926e6bb3c343 Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Sat, 11 Mar 2023 21:40:42 +0100 Subject: [PATCH 042/150] update php-amqplib - reverted to minimal requirement update --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index c29cd7d2..94bfc356 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ "php": "^8.0", "ext-json": "*", "illuminate/queue": "^9.0|^10.0", - "php-amqplib/php-amqplib": "^v3.2.0" + "php-amqplib/php-amqplib": "^v3.2" }, "require-dev": { "phpunit/phpunit": "^9.3", From 61f9142d8a09a14626c68c7c71171382092295e3 Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Sat, 11 Mar 2023 22:00:33 +0100 Subject: [PATCH 043/150] added: - factory for creating a config object. fixed: - tests removed: - unnecessary methods --- src/Queue/QueueConfigFactory.php | 74 ++++++++++++++++++++++++++++++++ src/Queue/QueueFactory.php | 39 +---------------- 2 files changed, 76 insertions(+), 37 deletions(-) create mode 100644 src/Queue/QueueConfigFactory.php diff --git a/src/Queue/QueueConfigFactory.php b/src/Queue/QueueConfigFactory.php new file mode 100644 index 00000000..6266cf20 --- /dev/null +++ b/src/Queue/QueueConfigFactory.php @@ -0,0 +1,74 @@ +setQueue($queue); + } + if (! empty($afterCommit = Arr::get($config, 'after_commit'))) { + $queueConfig->setDispatchAfterCommit($afterCommit); + } + + self::getOptionsFromConfig($queueConfig, $config); + }); + } + + private static function getOptionsFromConfig(QueueConfig $queueConfig, array $config): void + { + $queueOptions = Arr::get($config, self::CONFIG_OPTIONS.'.queue', []) ?: []; + + if ($job = Arr::pull($queueOptions, 'job')) { + $queueConfig->setAbstractJob($job); + } + + // Feature: Prioritize delayed messages. + if ($prioritizeDelayed = Arr::pull($queueOptions, 'prioritize_delayed')) { + $queueConfig->setPrioritizeDelayed($prioritizeDelayed); + } + if ($maxPriority = Arr::pull($queueOptions, 'queue_max_priority')) { + $queueConfig->setQueueMaxPriority($maxPriority); + } + + // Feature: Working with Exchange and routing-keys + if ($exchange = Arr::pull($queueOptions, 'exchange')) { + $queueConfig->setExchange($exchange); + } + if ($exchangeType = Arr::pull($queueOptions, 'exchange_type')) { + $queueConfig->setExchangeType($exchangeType); + } + if ($exchangeRoutingKey = Arr::pull($queueOptions, 'exchange_routing_key')) { + $queueConfig->setExchangeRoutingKey($exchangeRoutingKey); + } + + // Feature: Reroute failed messages + if ($rerouteFailed = Arr::pull($queueOptions, 'reroute_failed')) { + $queueConfig->setRerouteFailed($rerouteFailed); + } + if ($failedExchange = Arr::pull($queueOptions, 'failed_exchange')) { + $queueConfig->setFailedExchange($failedExchange); + } + if ($failedRoutingKey = Arr::pull($queueOptions, 'failed_routing_key')) { + $queueConfig->setFailedRoutingKey($failedRoutingKey); + } + + // Feature: Mark queue as quorum + if ($quorum = Arr::pull($queueOptions, 'quorum')) { + $queueConfig->setQuorum($quorum); + } + + // All extra options not defined + $queueConfig->setOptions($queueOptions); + } +} diff --git a/src/Queue/QueueFactory.php b/src/Queue/QueueFactory.php index 2595d8a4..75bde1ed 100644 --- a/src/Queue/QueueFactory.php +++ b/src/Queue/QueueFactory.php @@ -5,11 +5,11 @@ use Illuminate\Support\Arr; use VladimirYuldashev\LaravelQueueRabbitMQ\Horizon\RabbitMQQueue as HorizonRabbitMQQueue; -final class QueueFactory +class QueueFactory { public static function make(array $config = []): RabbitMQQueue { - $queueConfig = self::createQueueConfig($config); + $queueConfig = QueueConfigFactory::make($config); $worker = Arr::get($config, 'worker', 'default'); if (strtolower($worker) == 'default') { @@ -22,39 +22,4 @@ public static function make(array $config = []): RabbitMQQueue return new $worker($queueConfig); } - - /** - * Create a config object from config array - */ - private static function createQueueConfig(array $config = []): QueueConfig - { - return tap(new QueueConfig(), function (QueueConfig $queueConfig) use ($config) { - if (! empty($queue = Arr::get($config, 'queue'))) { - $queueConfig->setQueue($queue); - } - if (! empty($afterCommit = Arr::get($config, 'after_commit'))) { - $queueConfig->setDispatchAfterCommit($afterCommit); - } - - if (! empty($queueOptionsConfig = Arr::get($config, 'options.queue'))) { - $queueConfig - ->setAbstractJob(Arr::pull($queueOptionsConfig, 'job')) - // Feature: Prioritize delayed messages. - ->setPrioritizeDelayed(Arr::pull($queueOptionsConfig, 'prioritize_delayed')) - ->setQueueMaxPriority(Arr::pull($queueOptionsConfig, 'queue_max_priority')) - // Feature: Working with Exchange and routing-keys - ->setExchange(Arr::pull($queueOptionsConfig, 'exchange')) - ->setExchangeType(Arr::pull($queueOptionsConfig, 'exchange_type')) - ->setExchangeRoutingKey(Arr::pull($queueOptionsConfig, 'exchange_routing_key')) - // Feature: Reroute failed messages - ->setRerouteFailed(Arr::pull($queueOptionsConfig, 'reroute_failed')) - ->setFailedExchange(Arr::pull($queueOptionsConfig, 'failed_exchange')) - ->setFailedRoutingKey(Arr::pull($queueOptionsConfig, 'failed_routing_key')) - // Feature: Mark queue as quorum - ->setQuorum(Arr::pull($queueOptionsConfig, 'quorum')) - // All extra options not defined - ->setOptions($queueOptionsConfig); - } - }); - } } From 859fedaedb6e5575068fcccc035801013f7169da Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Sat, 11 Mar 2023 22:01:28 +0100 Subject: [PATCH 044/150] cleanup --- src/Queue/Connection/ConfigFactory.php | 18 +++++++++--------- src/Queue/Connection/ConnectionFactory.php | 14 +++++++------- src/Queue/QueueConfig.php | 6 ++++-- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/Queue/Connection/ConfigFactory.php b/src/Queue/Connection/ConfigFactory.php index 3e5e0c14..9e27529d 100644 --- a/src/Queue/Connection/ConfigFactory.php +++ b/src/Queue/Connection/ConfigFactory.php @@ -5,12 +5,12 @@ use Illuminate\Support\Arr; use PhpAmqpLib\Connection\AMQPConnectionConfig; -class ConfigFactory +final class ConfigFactory { - protected const CONFIG_OPTIONS = 'options'; - public const CONFIG_HOSTS = 'hosts'; + private const CONFIG_OPTIONS = 'options'; + /** * Create a config object from config array */ @@ -32,15 +32,15 @@ public static function make(array $config = []): AMQPConnectionConfig ); if ($connectionConfig->isSecure()) { - self::sllOptionsFromConfig($connectionConfig, $config); + self::getSLLOptionsFromConfig($connectionConfig, $config); } - self::hostFromConfig($connectionConfig, $config); - self::heartbeatFromConfig($connectionConfig, $config); + self::getHostFromConfig($connectionConfig, $config); + self::getHeartbeatFromConfig($connectionConfig, $config); }); } - protected static function hostFromConfig(AMQPConnectionConfig $connectionConfig, array $config): void + private static function getHostFromConfig(AMQPConnectionConfig $connectionConfig, array $config): void { $hostConfig = Arr::first(Arr::shuffle(Arr::get($config, self::CONFIG_HOSTS, [])), null, []); @@ -61,7 +61,7 @@ protected static function hostFromConfig(AMQPConnectionConfig $connectionConfig, } } - protected static function sllOptionsFromConfig(AMQPConnectionConfig $connectionConfig, array $config): void + private static function getSLLOptionsFromConfig(AMQPConnectionConfig $connectionConfig, array $config): void { $sslConfig = Arr::get($config, self::CONFIG_OPTIONS.'.ssl_options', []); @@ -82,7 +82,7 @@ protected static function sllOptionsFromConfig(AMQPConnectionConfig $connectionC } } - protected static function heartbeatFromConfig(AMQPConnectionConfig $connectionConfig, array $config): void + private static function getHeartbeatFromConfig(AMQPConnectionConfig $connectionConfig, array $config): void { $heartbeat = Arr::get($config, self::CONFIG_OPTIONS.'.heartbeat'); diff --git a/src/Queue/Connection/ConnectionFactory.php b/src/Queue/Connection/ConnectionFactory.php index d9879dbe..2ad99176 100644 --- a/src/Queue/Connection/ConnectionFactory.php +++ b/src/Queue/Connection/ConnectionFactory.php @@ -17,17 +17,17 @@ class ConnectionFactory { - protected const CONNECTION_TYPE_DEFAULT = 'default'; + private const CONNECTION_TYPE_DEFAULT = 'default'; - protected const CONNECTION_TYPE_EXTENDED = AbstractConnection::class; + private const CONNECTION_TYPE_EXTENDED = AbstractConnection::class; - protected const CONNECTION_SUB_TYPE_STREAM = AMQPStreamConnection::class; + private const CONNECTION_SUB_TYPE_STREAM = AMQPStreamConnection::class; - protected const CONNECTION_SUB_TYPE_SOCKET = AMQPSocketConnection::class; + private const CONNECTION_SUB_TYPE_SOCKET = AMQPSocketConnection::class; - protected const CONNECTION_SUB_TYPE_SSL = AMQPSSLConnection::class; + private const CONNECTION_SUB_TYPE_SSL = AMQPSSLConnection::class; - protected const CONFIG_CONNECTION = 'connection'; + private const CONFIG_CONNECTION = 'connection'; /** * Create a Connection @@ -152,7 +152,7 @@ private static function createStreamConnection($connection, AMQPConnectionConfig ); } - protected static function getReadWriteTimeout(AMQPConnectionConfig $config): float + private static function getReadWriteTimeout(AMQPConnectionConfig $config): float { return min($config->getReadTimeout(), $config->getWriteTimeout()); } diff --git a/src/Queue/QueueConfig.php b/src/Queue/QueueConfig.php index 6c4b5d49..7d3d6654 100644 --- a/src/Queue/QueueConfig.php +++ b/src/Queue/QueueConfig.php @@ -4,7 +4,7 @@ use VladimirYuldashev\LaravelQueueRabbitMQ\Queue\Jobs\RabbitMQJob; -class QueueConfig +final class QueueConfig { private string $queue = 'default'; @@ -109,7 +109,9 @@ public function getQueueMaxPriority(): int public function setQueueMaxPriority($queueMaxPriority): QueueConfig { - $this->queueMaxPriority = is_numeric($queueMaxPriority) ? (int) $queueMaxPriority : 2; + if (is_numeric($queueMaxPriority)) { + $this->queueMaxPriority = (int) $queueMaxPriority; + } return $this; } From 86181424f75fc6b03e75aa1c346ed28e908f26b5 Mon Sep 17 00:00:00 2001 From: Seb Date: Mon, 13 Mar 2023 13:33:50 -0700 Subject: [PATCH 045/150] Honor the 'rest' option --- src/Consumer.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Consumer.php b/src/Consumer.php index bd7f099d..a868d436 100644 --- a/src/Consumer.php +++ b/src/Consumer.php @@ -125,6 +125,10 @@ function (AMQPMessage $message) use ($connection, $options, $connectionName, $qu if ($this->supportsAsyncSignals()) { $this->resetTimeoutHandler(); } + + if ($options->rest > 0) { + sleep($options->rest); + } }, null, $arguments From e54d287dca2f70475adc97e163281a83be855d5b Mon Sep 17 00:00:00 2001 From: Seb Date: Mon, 13 Mar 2023 14:52:44 -0700 Subject: [PATCH 046/150] missed this --- src/Consumer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Consumer.php b/src/Consumer.php index a868d436..ed3d8099 100644 --- a/src/Consumer.php +++ b/src/Consumer.php @@ -127,7 +127,7 @@ function (AMQPMessage $message) use ($connection, $options, $connectionName, $qu } if ($options->rest > 0) { - sleep($options->rest); + $this->sleep($options->rest); } }, null, From 0e9c529550ed3cb2efe6f40bc77c8db41f30cff4 Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Wed, 15 Mar 2023 14:52:33 +0100 Subject: [PATCH 047/150] added: OctaneRabbitMQQueue::class --- src/Octane/RabbitMQQueue.php | 30 ++++++++++++++++++++++++++++++ src/Queue/QueueFactory.php | 5 +++++ 2 files changed, 35 insertions(+) create mode 100644 src/Octane/RabbitMQQueue.php diff --git a/src/Octane/RabbitMQQueue.php b/src/Octane/RabbitMQQueue.php new file mode 100644 index 00000000..e6bb8cb2 --- /dev/null +++ b/src/Octane/RabbitMQQueue.php @@ -0,0 +1,30 @@ +reconnect(); + parent::publishBasic($msg, $exchange, $destination, $mandatory, $immediate, $ticket); + } + } + + protected function publishBatch(): void + { + try { + parent::publishBatch(); + } catch (AMQPConnectionClosedException|AMQPChannelClosedException $exception) { + $this->reconnect(); + parent::publishBatch(); + } + } +} diff --git a/src/Queue/QueueFactory.php b/src/Queue/QueueFactory.php index 75bde1ed..ee29752b 100644 --- a/src/Queue/QueueFactory.php +++ b/src/Queue/QueueFactory.php @@ -4,6 +4,7 @@ use Illuminate\Support\Arr; use VladimirYuldashev\LaravelQueueRabbitMQ\Horizon\RabbitMQQueue as HorizonRabbitMQQueue; +use VladimirYuldashev\LaravelQueueRabbitMQ\Octane\RabbitMQQueue as OctaneRabbitMQQueue; class QueueFactory { @@ -20,6 +21,10 @@ public static function make(array $config = []): RabbitMQQueue return new HorizonRabbitMQQueue($queueConfig); } + if (strtolower($worker) == 'octane') { + return new OctaneRabbitMQQueue($queueConfig); + } + return new $worker($queueConfig); } } From 7d1ef065b4c87e4f4aaff3465fa157cd42575369 Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Wed, 15 Mar 2023 14:59:54 +0100 Subject: [PATCH 048/150] cleanup: - Connection disconnected by default (Lazy) - refactored publish methods --- src/Queue/RabbitMQQueue.php | 43 ++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/src/Queue/RabbitMQQueue.php b/src/Queue/RabbitMQQueue.php index 22cced8b..8c67cc6d 100644 --- a/src/Queue/RabbitMQQueue.php +++ b/src/Queue/RabbitMQQueue.php @@ -19,6 +19,7 @@ use PhpAmqpLib\Exchange\AMQPExchangeType; use PhpAmqpLib\Message\AMQPMessage; use PhpAmqpLib\Wire\AMQPTable; +use RuntimeException; use Throwable; use VladimirYuldashev\LaravelQueueRabbitMQ\Contracts\RabbitMQQueueContract; use VladimirYuldashev\LaravelQueueRabbitMQ\Queue\Jobs\RabbitMQJob; @@ -28,12 +29,12 @@ class RabbitMQQueue extends Queue implements QueueContract, RabbitMQQueueContrac /** * The RabbitMQ connection instance. */ - protected AbstractConnection $connection; + protected ?AbstractConnection $connection = null; /** * The RabbitMQ channel instance. */ - protected AMQPChannel $channel; + protected ?AMQPChannel $channel = null; /** * List of already declared exchanges. @@ -121,7 +122,7 @@ public function pushRaw($payload, $queue = null, array $options = []): int|strin [$message, $correlationId] = $this->createMessage($payload, $attempts); - $this->getChannel()->basic_publish($message, $exchange, $destination, true); + $this->publishBasic($message, $exchange, $destination, true); return $correlationId; } @@ -145,8 +146,6 @@ function ($payload, $queue, $delay) { } /** - * @param null $queue - * * @throws AMQPProtocolChannelException */ public function laterRaw($delay, string $payload, $queue = null, int $attempts = 0): int|string|null @@ -172,7 +171,7 @@ public function laterRaw($delay, string $payload, $queue = null, int $attempts = [$message, $correlationId] = $this->createMessage($payload, $attempts); // Publish directly on the delayQueue, no need to publish through an exchange. - $this->getChannel()->basic_publish($message, null, $destination, true); + $this->publishBasic($message, null, $destination, true); return $correlationId; } @@ -188,7 +187,7 @@ public function bulk($jobs, $data = '', $queue = null): void $this->bulkRaw($this->createPayload($job, $queue, $data), $queue, ['job' => $job]); } - $this->getChannel()->publish_batch(); + $this->publishBatch(); } /** @@ -235,7 +234,7 @@ public function pop($queue = null) if ($exception->amqp_reply_code === 404) { // Because of the channel exception the channel was closed and removed. // We have to open a new channel. Because else the worker(s) are stuck in a loop, without processing. - $this->channel = $this->getConnection()->channel(); + $this->getChannel(true); return null; } @@ -256,21 +255,31 @@ public function pop($queue = null) return null; } + /** + * @throws RuntimeException + */ public function getConnection(): AbstractConnection { + if (! $this->connection) { + throw new RuntimeException('Queue has no AMQPConnection set.'); + } + return $this->connection; } public function setConnection(AbstractConnection $connection): RabbitMQQueue { $this->connection = $connection; - $this->channel = $connection->channel(); return $this; } - public function getChannel(): AMQPChannel + public function getChannel($forceNew = false): AMQPChannel { + if (! $this->channel || $forceNew) { + $this->channel = $this->getConnection()->channel(); + } + return $this->channel; } @@ -563,7 +572,7 @@ public function close(): void } try { - $this->connection->close(); + $this->getConnection()->close(); } catch (ErrorException) { // Ignore the exception } @@ -709,8 +718,18 @@ protected function publishProperties($queue, array $options = []): array return [$destination, $exchange, $exchangeType, $attempts]; } - private function getConfig(): QueueConfig + protected function getConfig(): QueueConfig { return $this->config; } + + protected function publishBasic($msg, $exchange = '', $destination = '', $mandatory = false, $immediate = false, $ticket = null): void + { + $this->getChannel()->basic_publish($msg, $exchange, $destination, $mandatory, $immediate, $ticket); + } + + protected function publishBatch(): void + { + $this->getChannel()->publish_batch(); + } } From e25d51bad78a0401da4cf42d1366a32356127119 Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Wed, 15 Mar 2023 15:00:38 +0100 Subject: [PATCH 049/150] test lazy: - Connection disconnected by default (Lazy) --- tests/Feature/ConnectorTest.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/Feature/ConnectorTest.php b/tests/Feature/ConnectorTest.php index 00cf5d6e..3ecede98 100644 --- a/tests/Feature/ConnectorTest.php +++ b/tests/Feature/ConnectorTest.php @@ -48,8 +48,9 @@ public function testLazyConnection(): void $this->assertInstanceOf(RabbitMQQueue::class, $connection); $this->assertInstanceOf(AMQPLazyConnection::class, $connection->getConnection()); - $this->assertTrue($connection->getConnection()->isConnected()); + $this->assertFalse($connection->getConnection()->isConnected()); $this->assertTrue($connection->getChannel()->is_open()); + $this->assertTrue($connection->getConnection()->isConnected()); } public function testLazyStreamConnection(): void @@ -90,8 +91,9 @@ public function testLazyStreamConnection(): void $this->assertInstanceOf(RabbitMQQueue::class, $connection); $this->assertInstanceOf(AMQPStreamConnection::class, $connection->getConnection()); - $this->assertTrue($connection->getConnection()->isConnected()); + $this->assertFalse($connection->getConnection()->isConnected()); $this->assertTrue($connection->getChannel()->is_open()); + $this->assertTrue($connection->getConnection()->isConnected()); } public function testSslConnection(): void From 1a17d4c24447660f6f729740c1315db5ba21999f Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Wed, 15 Mar 2023 15:08:21 +0100 Subject: [PATCH 050/150] added: reconnect() method --- src/Queue/RabbitMQQueue.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Queue/RabbitMQQueue.php b/src/Queue/RabbitMQQueue.php index 8c67cc6d..a228d714 100644 --- a/src/Queue/RabbitMQQueue.php +++ b/src/Queue/RabbitMQQueue.php @@ -283,6 +283,12 @@ public function getChannel($forceNew = false): AMQPChannel return $this->channel; } + protected function reconnect() + { + $this->getConnection()->reconnect(); + $this->getChannel(true); + } + /** * Job class to use. * From 722bc8361c28adc99ae185f14f0224e66e6876c8 Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Wed, 15 Mar 2023 15:09:38 +0100 Subject: [PATCH 051/150] cleanup --- src/Octane/RabbitMQQueue.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Octane/RabbitMQQueue.php b/src/Octane/RabbitMQQueue.php index e6bb8cb2..d9cd9890 100644 --- a/src/Octane/RabbitMQQueue.php +++ b/src/Octane/RabbitMQQueue.php @@ -12,7 +12,7 @@ protected function publishBasic($msg, $exchange = '', $destination = '', $mandat { try { parent::publishBasic($msg, $exchange, $destination, $mandatory, $immediate, $ticket); - } catch (AMQPConnectionClosedException|AMQPChannelClosedException $exception) { + } catch (AMQPConnectionClosedException|AMQPChannelClosedException) { $this->reconnect(); parent::publishBasic($msg, $exchange, $destination, $mandatory, $immediate, $ticket); } @@ -22,7 +22,7 @@ protected function publishBatch(): void { try { parent::publishBatch(); - } catch (AMQPConnectionClosedException|AMQPChannelClosedException $exception) { + } catch (AMQPConnectionClosedException|AMQPChannelClosedException) { $this->reconnect(); parent::publishBatch(); } From 5edfec546eff1ccf10d006e793287fbcc818fde6 Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Wed, 15 Mar 2023 15:16:51 +0100 Subject: [PATCH 052/150] moved (reconnect) methods to a trait --- src/Octane/RabbitMQQueue.php | 23 ++--------------------- src/Queue/ReconnectTrait.php | 29 +++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 21 deletions(-) create mode 100644 src/Queue/ReconnectTrait.php diff --git a/src/Octane/RabbitMQQueue.php b/src/Octane/RabbitMQQueue.php index d9cd9890..9e749efa 100644 --- a/src/Octane/RabbitMQQueue.php +++ b/src/Octane/RabbitMQQueue.php @@ -2,29 +2,10 @@ namespace VladimirYuldashev\LaravelQueueRabbitMQ\Octane; -use PhpAmqpLib\Exception\AMQPChannelClosedException; -use PhpAmqpLib\Exception\AMQPConnectionClosedException; use VladimirYuldashev\LaravelQueueRabbitMQ\Queue\RabbitMQQueue as BaseRabbitMQQueue; +use VladimirYuldashev\LaravelQueueRabbitMQ\Queue\ReconnectTrait; class RabbitMQQueue extends BaseRabbitMQQueue { - protected function publishBasic($msg, $exchange = '', $destination = '', $mandatory = false, $immediate = false, $ticket = null): void - { - try { - parent::publishBasic($msg, $exchange, $destination, $mandatory, $immediate, $ticket); - } catch (AMQPConnectionClosedException|AMQPChannelClosedException) { - $this->reconnect(); - parent::publishBasic($msg, $exchange, $destination, $mandatory, $immediate, $ticket); - } - } - - protected function publishBatch(): void - { - try { - parent::publishBatch(); - } catch (AMQPConnectionClosedException|AMQPChannelClosedException) { - $this->reconnect(); - parent::publishBatch(); - } - } + use ReconnectTrait; } diff --git a/src/Queue/ReconnectTrait.php b/src/Queue/ReconnectTrait.php new file mode 100644 index 00000000..41ec7395 --- /dev/null +++ b/src/Queue/ReconnectTrait.php @@ -0,0 +1,29 @@ +reconnect(); + parent::publishBasic($msg, $exchange, $destination, $mandatory, $immediate, $ticket); + } + } + + protected function publishBatch(): void + { + try { + parent::publishBatch(); + } catch (AMQPConnectionClosedException|AMQPChannelClosedException) { + $this->reconnect(); + parent::publishBatch(); + } + } +} From 0b6699161465e09708b4d3564107206de7e2b865 Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Wed, 15 Mar 2023 18:08:43 +0100 Subject: [PATCH 053/150] added tests --- tests/Functional/RabbitMQQueueTest.php | 67 ++++++++++++++++++++------ tests/Functional/TestCase.php | 22 ++++++++- 2 files changed, 72 insertions(+), 17 deletions(-) diff --git a/tests/Functional/RabbitMQQueueTest.php b/tests/Functional/RabbitMQQueueTest.php index 5a50342b..69f8c4b4 100644 --- a/tests/Functional/RabbitMQQueueTest.php +++ b/tests/Functional/RabbitMQQueueTest.php @@ -2,10 +2,14 @@ namespace VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Functional; +use Illuminate\Support\Facades\Queue; use Illuminate\Support\Str; +use PhpAmqpLib\Exception\AMQPChannelClosedException; use PhpAmqpLib\Exchange\AMQPExchangeType; +use VladimirYuldashev\LaravelQueueRabbitMQ\Octane\RabbitMQQueue as OctaneRabbitMQQueue; use VladimirYuldashev\LaravelQueueRabbitMQ\Queue\RabbitMQQueue; use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Functional\TestCase as BaseTestCase; +use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Mocks\TestJob; class RabbitMQQueueTest extends BaseTestCase { @@ -19,6 +23,10 @@ public function testConnection(): void $queue = $this->connection('rabbitmq-with-options-empty'); $this->assertInstanceOf(RabbitMQQueue::class, $queue); + + $queue = $this->connection('rabbitmq-with-octane-reconnect-options'); + $this->assertInstanceOf(RabbitMQQueue::class, $queue); + $this->assertInstanceOf(OctaneRabbitMQQueue::class, $queue); } public function testConfigRerouteFailed(): void @@ -180,14 +188,14 @@ public function testQueueArguments(): void { $name = Str::random(); - $queue = $this->connection(); - $actual = $this->callMethod($queue, 'getQueueArguments', [$name]); + $queue = $this->connection(); + $actual = $this->callMethod($queue, 'getQueueArguments', [$name]); $expected = []; $this->assertEquals(array_keys($expected), array_keys($actual)); $this->assertEquals(array_values($expected), array_values($actual)); - $queue = $this->connection('rabbitmq-with-options'); - $actual = $this->callMethod($queue, 'getQueueArguments', [$name]); + $queue = $this->connection('rabbitmq-with-options'); + $actual = $this->callMethod($queue, 'getQueueArguments', [$name]); $expected = [ 'x-max-priority' => 20, 'x-dead-letter-exchange' => 'failed-exchange', @@ -197,8 +205,8 @@ public function testQueueArguments(): void $this->assertEquals(array_keys($expected), array_keys($actual)); $this->assertEquals(array_values($expected), array_values($actual)); - $queue = $this->connection('rabbitmq-with-quorum-options'); - $actual = $this->callMethod($queue, 'getQueueArguments', [$name]); + $queue = $this->connection('rabbitmq-with-quorum-options'); + $actual = $this->callMethod($queue, 'getQueueArguments', [$name]); $expected = [ 'x-dead-letter-exchange' => 'failed-exchange', 'x-dead-letter-routing-key' => sprintf('application-x.%s.failed', $name), @@ -208,8 +216,8 @@ public function testQueueArguments(): void $this->assertEquals(array_keys($expected), array_keys($actual)); $this->assertEquals(array_values($expected), array_values($actual)); - $queue = $this->connection('rabbitmq-with-options-empty'); - $actual = $this->callMethod($queue, 'getQueueArguments', [$name]); + $queue = $this->connection('rabbitmq-with-options-empty'); + $actual = $this->callMethod($queue, 'getQueueArguments', [$name]); $expected = []; $this->assertEquals(array_keys($expected), array_keys($actual)); @@ -219,10 +227,10 @@ public function testQueueArguments(): void public function testDelayQueueArguments(): void { $name = Str::random(); - $ttl = 12000; + $ttl = 12000; - $queue = $this->connection(); - $actual = $this->callMethod($queue, 'getDelayQueueArguments', [$name, $ttl]); + $queue = $this->connection(); + $actual = $this->callMethod($queue, 'getDelayQueueArguments', [$name, $ttl]); $expected = [ 'x-dead-letter-exchange' => '', 'x-dead-letter-routing-key' => $name, @@ -232,8 +240,8 @@ public function testDelayQueueArguments(): void $this->assertEquals(array_keys($expected), array_keys($actual)); $this->assertEquals(array_values($expected), array_values($actual)); - $queue = $this->connection('rabbitmq-with-options'); - $actual = $this->callMethod($queue, 'getDelayQueueArguments', [$name, $ttl]); + $queue = $this->connection('rabbitmq-with-options'); + $actual = $this->callMethod($queue, 'getDelayQueueArguments', [$name, $ttl]); $expected = [ 'x-dead-letter-exchange' => 'application-x', 'x-dead-letter-routing-key' => sprintf('process.%s', $name), @@ -243,8 +251,8 @@ public function testDelayQueueArguments(): void $this->assertEquals(array_keys($expected), array_keys($actual)); $this->assertEquals(array_values($expected), array_values($actual)); - $queue = $this->connection('rabbitmq-with-options-empty'); - $actual = $this->callMethod($queue, 'getDelayQueueArguments', [$name, $ttl]); + $queue = $this->connection('rabbitmq-with-options-empty'); + $actual = $this->callMethod($queue, 'getDelayQueueArguments', [$name, $ttl]); $expected = [ 'x-dead-letter-exchange' => '', 'x-dead-letter-routing-key' => $name, @@ -254,4 +262,33 @@ public function testDelayQueueArguments(): void $this->assertEquals(array_keys($expected), array_keys($actual)); $this->assertEquals(array_values($expected), array_values($actual)); } + + public function testWithoutReconnect(): void + { + $queue = $this->connection(); + $queue->purge(); + // Lazy connection + $queue->push(new TestJob()); + sleep(1); + $this->assertSame(1, $queue->size()); + + $queue->getConnection()->close(); + $this->assertFalse($queue->getConnection()->isConnected()); + $this->assertThrows(fn() => $queue->push(new TestJob()), AMQPChannelClosedException::class); + } + + public function testReconnect(): void + { + $queue = $this->connection('rabbitmq-with-octane-reconnect-options'); + $queue->purge(); + $queue->push(new TestJob()); + sleep(1); + $this->assertSame(1, $queue->size()); + $queue->getConnection()->close(); + $this->assertFalse($queue->getConnection()->isConnected()); + $queue->push(new TestJob()); + sleep(1); + $this->assertTrue($queue->getConnection()->isConnected()); + $this->assertSame(2, $queue->size()); + } } diff --git a/tests/Functional/TestCase.php b/tests/Functional/TestCase.php index 4edc8853..384e0cef 100644 --- a/tests/Functional/TestCase.php +++ b/tests/Functional/TestCase.php @@ -157,6 +157,24 @@ protected function getEnvironmentSetUp($app): void 'worker' => 'default', ]); + $app['config']->set('queue.connections.rabbitmq-with-octane-reconnect-options', [ + 'driver' => 'rabbitmq', + 'queue' => 'default', + 'connection' => 'default', + + 'hosts' => [ + [ + 'host' => getenv('HOST'), + 'port' => getenv('PORT'), + 'vhost' => '/', + 'user' => 'guest', + 'password' => 'guest', + ], + ], + + 'worker' => 'octane', + + ]); } /** @@ -165,7 +183,7 @@ protected function getEnvironmentSetUp($app): void protected function callMethod($object, string $method, array $parameters = []): mixed { try { - $className = get_class($object); + $className = get_class($object); $reflection = new ReflectionClass($className); } catch (ReflectionException $e) { throw new Exception($e->getMessage()); @@ -183,7 +201,7 @@ protected function callMethod($object, string $method, array $parameters = []): protected function callProperty($object, string $property): mixed { try { - $className = get_class($object); + $className = get_class($object); $reflection = new ReflectionClass($className); } catch (ReflectionException $e) { throw new Exception($e->getMessage()); From 326cb5171dc70304214bda888f6ac1a30e6051fe Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Wed, 15 Mar 2023 18:08:56 +0100 Subject: [PATCH 054/150] added tests --- tests/Functional/RabbitMQQueueTest.php | 33 +++++++++++++------------- tests/Functional/TestCase.php | 4 ++-- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/tests/Functional/RabbitMQQueueTest.php b/tests/Functional/RabbitMQQueueTest.php index 69f8c4b4..9bad51f5 100644 --- a/tests/Functional/RabbitMQQueueTest.php +++ b/tests/Functional/RabbitMQQueueTest.php @@ -2,7 +2,6 @@ namespace VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Functional; -use Illuminate\Support\Facades\Queue; use Illuminate\Support\Str; use PhpAmqpLib\Exception\AMQPChannelClosedException; use PhpAmqpLib\Exchange\AMQPExchangeType; @@ -188,14 +187,14 @@ public function testQueueArguments(): void { $name = Str::random(); - $queue = $this->connection(); - $actual = $this->callMethod($queue, 'getQueueArguments', [$name]); + $queue = $this->connection(); + $actual = $this->callMethod($queue, 'getQueueArguments', [$name]); $expected = []; $this->assertEquals(array_keys($expected), array_keys($actual)); $this->assertEquals(array_values($expected), array_values($actual)); - $queue = $this->connection('rabbitmq-with-options'); - $actual = $this->callMethod($queue, 'getQueueArguments', [$name]); + $queue = $this->connection('rabbitmq-with-options'); + $actual = $this->callMethod($queue, 'getQueueArguments', [$name]); $expected = [ 'x-max-priority' => 20, 'x-dead-letter-exchange' => 'failed-exchange', @@ -205,8 +204,8 @@ public function testQueueArguments(): void $this->assertEquals(array_keys($expected), array_keys($actual)); $this->assertEquals(array_values($expected), array_values($actual)); - $queue = $this->connection('rabbitmq-with-quorum-options'); - $actual = $this->callMethod($queue, 'getQueueArguments', [$name]); + $queue = $this->connection('rabbitmq-with-quorum-options'); + $actual = $this->callMethod($queue, 'getQueueArguments', [$name]); $expected = [ 'x-dead-letter-exchange' => 'failed-exchange', 'x-dead-letter-routing-key' => sprintf('application-x.%s.failed', $name), @@ -216,8 +215,8 @@ public function testQueueArguments(): void $this->assertEquals(array_keys($expected), array_keys($actual)); $this->assertEquals(array_values($expected), array_values($actual)); - $queue = $this->connection('rabbitmq-with-options-empty'); - $actual = $this->callMethod($queue, 'getQueueArguments', [$name]); + $queue = $this->connection('rabbitmq-with-options-empty'); + $actual = $this->callMethod($queue, 'getQueueArguments', [$name]); $expected = []; $this->assertEquals(array_keys($expected), array_keys($actual)); @@ -227,10 +226,10 @@ public function testQueueArguments(): void public function testDelayQueueArguments(): void { $name = Str::random(); - $ttl = 12000; + $ttl = 12000; - $queue = $this->connection(); - $actual = $this->callMethod($queue, 'getDelayQueueArguments', [$name, $ttl]); + $queue = $this->connection(); + $actual = $this->callMethod($queue, 'getDelayQueueArguments', [$name, $ttl]); $expected = [ 'x-dead-letter-exchange' => '', 'x-dead-letter-routing-key' => $name, @@ -240,8 +239,8 @@ public function testDelayQueueArguments(): void $this->assertEquals(array_keys($expected), array_keys($actual)); $this->assertEquals(array_values($expected), array_values($actual)); - $queue = $this->connection('rabbitmq-with-options'); - $actual = $this->callMethod($queue, 'getDelayQueueArguments', [$name, $ttl]); + $queue = $this->connection('rabbitmq-with-options'); + $actual = $this->callMethod($queue, 'getDelayQueueArguments', [$name, $ttl]); $expected = [ 'x-dead-letter-exchange' => 'application-x', 'x-dead-letter-routing-key' => sprintf('process.%s', $name), @@ -251,8 +250,8 @@ public function testDelayQueueArguments(): void $this->assertEquals(array_keys($expected), array_keys($actual)); $this->assertEquals(array_values($expected), array_values($actual)); - $queue = $this->connection('rabbitmq-with-options-empty'); - $actual = $this->callMethod($queue, 'getDelayQueueArguments', [$name, $ttl]); + $queue = $this->connection('rabbitmq-with-options-empty'); + $actual = $this->callMethod($queue, 'getDelayQueueArguments', [$name, $ttl]); $expected = [ 'x-dead-letter-exchange' => '', 'x-dead-letter-routing-key' => $name, @@ -274,7 +273,7 @@ public function testWithoutReconnect(): void $queue->getConnection()->close(); $this->assertFalse($queue->getConnection()->isConnected()); - $this->assertThrows(fn() => $queue->push(new TestJob()), AMQPChannelClosedException::class); + $this->assertThrows(fn () => $queue->push(new TestJob()), AMQPChannelClosedException::class); } public function testReconnect(): void diff --git a/tests/Functional/TestCase.php b/tests/Functional/TestCase.php index 384e0cef..b57fd768 100644 --- a/tests/Functional/TestCase.php +++ b/tests/Functional/TestCase.php @@ -183,7 +183,7 @@ protected function getEnvironmentSetUp($app): void protected function callMethod($object, string $method, array $parameters = []): mixed { try { - $className = get_class($object); + $className = get_class($object); $reflection = new ReflectionClass($className); } catch (ReflectionException $e) { throw new Exception($e->getMessage()); @@ -201,7 +201,7 @@ protected function callMethod($object, string $method, array $parameters = []): protected function callProperty($object, string $property): mixed { try { - $className = get_class($object); + $className = get_class($object); $reflection = new ReflectionClass($className); } catch (ReflectionException $e) { throw new Exception($e->getMessage()); From c3d53dbd234c919a20a909e37095f24ba1575d3c Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Thu, 16 Mar 2023 10:58:58 +0100 Subject: [PATCH 055/150] added tests --- tests/Feature/QueueTest.php | 44 ++++++++++++++++++++++++++ tests/Functional/RabbitMQQueueTest.php | 31 ------------------ tests/TestCase.php | 20 ++++++++++++ 3 files changed, 64 insertions(+), 31 deletions(-) diff --git a/tests/Feature/QueueTest.php b/tests/Feature/QueueTest.php index 3258b7f2..357d9b01 100644 --- a/tests/Feature/QueueTest.php +++ b/tests/Feature/QueueTest.php @@ -3,11 +3,55 @@ namespace VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Feature; use PhpAmqpLib\Connection\AMQPStreamConnection; +use PhpAmqpLib\Exception\AMQPChannelClosedException; +use PhpAmqpLib\Exception\AMQPConnectionClosedException; +use PhpAmqpLib\Exception\AMQPProtocolChannelException; +use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Mocks\TestJob; class QueueTest extends TestCase { + public function setUp(): void + { + parent::setUp(); + + $this->withoutExceptionHandling([AMQPChannelClosedException::class, AMQPConnectionClosedException::class, AMQPProtocolChannelException::class]); + } + public function testConnection(): void { $this->assertInstanceOf(AMQPStreamConnection::class, $this->connection()->getChannel()->getConnection()); } + + public function testWithoutReconnect(): void + { + $queue = $this->connection('rabbitmq'); + + $queue->push(new TestJob()); + sleep(1); + $this->assertSame(1, $queue->size()); + + // close connection + $queue->getConnection()->close(); + $this->assertFalse($queue->getConnection()->isConnected()); + + $this->assertThrows(fn () => $queue->push(new TestJob()), AMQPChannelClosedException::class); + } + + public function testReconnect(): void + { + $queue = $this->connection('octane'); + + $queue->push(new TestJob()); + sleep(1); + $this->assertSame(1, $queue->size()); + + // close connection + $queue->getConnection()->close(); + $this->assertFalse($queue->getConnection()->isConnected()); + + $queue->push(new TestJob()); + sleep(1); + $this->assertTrue($queue->getConnection()->isConnected()); + $this->assertSame(2, $queue->size()); + } } diff --git a/tests/Functional/RabbitMQQueueTest.php b/tests/Functional/RabbitMQQueueTest.php index 9bad51f5..fac5e889 100644 --- a/tests/Functional/RabbitMQQueueTest.php +++ b/tests/Functional/RabbitMQQueueTest.php @@ -3,12 +3,10 @@ namespace VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Functional; use Illuminate\Support\Str; -use PhpAmqpLib\Exception\AMQPChannelClosedException; use PhpAmqpLib\Exchange\AMQPExchangeType; use VladimirYuldashev\LaravelQueueRabbitMQ\Octane\RabbitMQQueue as OctaneRabbitMQQueue; use VladimirYuldashev\LaravelQueueRabbitMQ\Queue\RabbitMQQueue; use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Functional\TestCase as BaseTestCase; -use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Mocks\TestJob; class RabbitMQQueueTest extends BaseTestCase { @@ -261,33 +259,4 @@ public function testDelayQueueArguments(): void $this->assertEquals(array_keys($expected), array_keys($actual)); $this->assertEquals(array_values($expected), array_values($actual)); } - - public function testWithoutReconnect(): void - { - $queue = $this->connection(); - $queue->purge(); - // Lazy connection - $queue->push(new TestJob()); - sleep(1); - $this->assertSame(1, $queue->size()); - - $queue->getConnection()->close(); - $this->assertFalse($queue->getConnection()->isConnected()); - $this->assertThrows(fn () => $queue->push(new TestJob()), AMQPChannelClosedException::class); - } - - public function testReconnect(): void - { - $queue = $this->connection('rabbitmq-with-octane-reconnect-options'); - $queue->purge(); - $queue->push(new TestJob()); - sleep(1); - $this->assertSame(1, $queue->size()); - $queue->getConnection()->close(); - $this->assertFalse($queue->getConnection()->isConnected()); - $queue->push(new TestJob()); - sleep(1); - $this->assertTrue($queue->getConnection()->isConnected()); - $this->assertSame(2, $queue->size()); - } } diff --git a/tests/TestCase.php b/tests/TestCase.php index 7d50fa67..9bea59b3 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -48,6 +48,26 @@ protected function getEnvironmentSetUp($app): void 'worker' => 'default', ]); + $app['config']->set('queue.connections.octane', [ + 'driver' => 'rabbitmq', + 'queue' => 'default', + 'connection' => AMQPLazyConnection::class, + + 'hosts' => [ + [ + 'host' => getenv('HOST'), + 'port' => getenv('PORT'), + 'vhost' => '/', + 'user' => 'guest', + 'password' => 'guest', + ], + ], + + 'options' => [], + + 'worker' => 'octane', + + ]); } protected function connection(string $name = null): RabbitMQQueue From e53fea0ecc90574f8bd5f7b6c8cd18a1978771ba Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Thu, 16 Mar 2023 11:20:44 +0100 Subject: [PATCH 056/150] updated: - removed `final` - changed `private` to `protected` --- src/Queue/Connection/ConfigFactory.php | 10 +++--- src/Queue/Connection/ConnectionFactory.php | 36 +++++++++++----------- src/Queue/Connectors/RabbitMQConnector.php | 2 +- src/Queue/QueueConfig.php | 28 ++++++++--------- src/Queue/QueueConfigFactory.php | 4 +-- 5 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/Queue/Connection/ConfigFactory.php b/src/Queue/Connection/ConfigFactory.php index 9e27529d..4b8f87a1 100644 --- a/src/Queue/Connection/ConfigFactory.php +++ b/src/Queue/Connection/ConfigFactory.php @@ -5,11 +5,11 @@ use Illuminate\Support\Arr; use PhpAmqpLib\Connection\AMQPConnectionConfig; -final class ConfigFactory +class ConfigFactory { public const CONFIG_HOSTS = 'hosts'; - private const CONFIG_OPTIONS = 'options'; + protected const CONFIG_OPTIONS = 'options'; /** * Create a config object from config array @@ -40,7 +40,7 @@ public static function make(array $config = []): AMQPConnectionConfig }); } - private static function getHostFromConfig(AMQPConnectionConfig $connectionConfig, array $config): void + protected static function getHostFromConfig(AMQPConnectionConfig $connectionConfig, array $config): void { $hostConfig = Arr::first(Arr::shuffle(Arr::get($config, self::CONFIG_HOSTS, [])), null, []); @@ -61,7 +61,7 @@ private static function getHostFromConfig(AMQPConnectionConfig $connectionConfig } } - private static function getSLLOptionsFromConfig(AMQPConnectionConfig $connectionConfig, array $config): void + protected static function getSLLOptionsFromConfig(AMQPConnectionConfig $connectionConfig, array $config): void { $sslConfig = Arr::get($config, self::CONFIG_OPTIONS.'.ssl_options', []); @@ -82,7 +82,7 @@ private static function getSLLOptionsFromConfig(AMQPConnectionConfig $connection } } - private static function getHeartbeatFromConfig(AMQPConnectionConfig $connectionConfig, array $config): void + protected static function getHeartbeatFromConfig(AMQPConnectionConfig $connectionConfig, array $config): void { $heartbeat = Arr::get($config, self::CONFIG_OPTIONS.'.heartbeat'); diff --git a/src/Queue/Connection/ConnectionFactory.php b/src/Queue/Connection/ConnectionFactory.php index 2ad99176..df19f223 100644 --- a/src/Queue/Connection/ConnectionFactory.php +++ b/src/Queue/Connection/ConnectionFactory.php @@ -17,17 +17,17 @@ class ConnectionFactory { - private const CONNECTION_TYPE_DEFAULT = 'default'; + protected const CONNECTION_TYPE_DEFAULT = 'default'; - private const CONNECTION_TYPE_EXTENDED = AbstractConnection::class; + protected const CONNECTION_TYPE_EXTENDED = AbstractConnection::class; - private const CONNECTION_SUB_TYPE_STREAM = AMQPStreamConnection::class; + protected const CONNECTION_SUB_TYPE_STREAM = AMQPStreamConnection::class; - private const CONNECTION_SUB_TYPE_SOCKET = AMQPSocketConnection::class; + protected const CONNECTION_SUB_TYPE_SOCKET = AMQPSocketConnection::class; - private const CONNECTION_SUB_TYPE_SSL = AMQPSSLConnection::class; + protected const CONNECTION_SUB_TYPE_SSL = AMQPSSLConnection::class; - private const CONFIG_CONNECTION = 'connection'; + protected const CONFIG_CONNECTION = 'connection'; /** * Create a Connection @@ -58,7 +58,7 @@ public static function make(array $config = []): AbstractConnection /** * Get the validated connection from config */ - private static function getConnectionFromConfig(array $config): string + protected static function getConnectionFromConfig(array $config): string { $connection = (string) Arr::get($config, self::CONFIG_CONNECTION, self::CONNECTION_TYPE_DEFAULT); @@ -70,7 +70,7 @@ private static function getConnectionFromConfig(array $config): string /** * Creation of your own connection */ - private static function create($connection, AMQPConnectionConfig $config): AbstractConnection + protected static function create($connection, AMQPConnectionConfig $config): AbstractConnection { if ($config->getIoType() === AMQPConnectionConfig::IO_TYPE_SOCKET) { return self::createSocketConnection($connection, $config); @@ -79,7 +79,7 @@ private static function create($connection, AMQPConnectionConfig $config): Abstr return self::createStreamConnection($connection, $config); } - private static function createSocketConnection($connection, AMQPConnectionConfig $config): AMQPSocketConnection + protected static function createSocketConnection($connection, AMQPConnectionConfig $config): AMQPSocketConnection { self::assertSocketConnection($connection, $config); @@ -102,7 +102,7 @@ private static function createSocketConnection($connection, AMQPConnectionConfig ); } - private static function createStreamConnection($connection, AMQPConnectionConfig $config): AMQPStreamConnection + protected static function createStreamConnection($connection, AMQPConnectionConfig $config): AMQPStreamConnection { self::assertStreamConnection($connection); @@ -152,12 +152,12 @@ private static function createStreamConnection($connection, AMQPConnectionConfig ); } - private static function getReadWriteTimeout(AMQPConnectionConfig $config): float + protected static function getReadWriteTimeout(AMQPConnectionConfig $config): float { return min($config->getReadTimeout(), $config->getWriteTimeout()); } - private static function getSslOptions(AMQPConnectionConfig $config): array + protected static function getSslOptions(AMQPConnectionConfig $config): array { return array_filter([ 'cafile' => $config->getSslCaCert(), @@ -174,14 +174,14 @@ private static function getSslOptions(AMQPConnectionConfig $config): array }); } - private static function assertConnectionFromConfig(string $connection): void + protected static function assertConnectionFromConfig(string $connection): void { if ($connection !== self::CONNECTION_TYPE_DEFAULT && ! is_subclass_of($connection, self::CONNECTION_TYPE_EXTENDED)) { throw new AMQPLogicException(sprintf('The config property \'%s\' must contain \'%s\' or must extend: %s', self::CONFIG_CONNECTION, self::CONNECTION_TYPE_DEFAULT, class_basename(self::CONNECTION_TYPE_EXTENDED))); } } - private static function assertSocketConnection($connection, AMQPConnectionConfig $config): void + protected static function assertSocketConnection($connection, AMQPConnectionConfig $config): void { self::assertExtendedOf($connection, self::CONNECTION_SUB_TYPE_SOCKET); @@ -190,17 +190,17 @@ private static function assertSocketConnection($connection, AMQPConnectionConfig } } - private static function assertStreamConnection($connection): void + protected static function assertStreamConnection($connection): void { self::assertExtendedOf($connection, self::CONNECTION_SUB_TYPE_STREAM); } - private static function assertSSLConnection($connection): void + protected static function assertSSLConnection($connection): void { self::assertExtendedOf($connection, self::CONNECTION_SUB_TYPE_SSL); } - private static function assertExtendedOf($connection, string $abstract): void + protected static function assertExtendedOf($connection, string $abstract): void { if (! is_subclass_of($connection, $abstract)) { throw new AMQPLogicException(sprintf('The connection must extend: %s', class_basename($abstract))); @@ -214,7 +214,7 @@ private static function assertExtendedOf($connection, string $abstract): void * * @deprecated This is the fallback method, update your config asap. (example: connection => 'default') */ - private static function _createLazyConnection($connection, array $config): AbstractConnection + protected static function _createLazyConnection($connection, array $config): AbstractConnection { return $connection::create_connection( Arr::shuffle(Arr::get($config, ConfigFactory::CONFIG_HOSTS, [])), diff --git a/src/Queue/Connectors/RabbitMQConnector.php b/src/Queue/Connectors/RabbitMQConnector.php index 97c964c1..a0f79e32 100644 --- a/src/Queue/Connectors/RabbitMQConnector.php +++ b/src/Queue/Connectors/RabbitMQConnector.php @@ -16,7 +16,7 @@ class RabbitMQConnector implements ConnectorInterface { - private Dispatcher $dispatcher; + protected Dispatcher $dispatcher; public function __construct(Dispatcher $dispatcher) { diff --git a/src/Queue/QueueConfig.php b/src/Queue/QueueConfig.php index 7d3d6654..b5aea131 100644 --- a/src/Queue/QueueConfig.php +++ b/src/Queue/QueueConfig.php @@ -4,33 +4,33 @@ use VladimirYuldashev\LaravelQueueRabbitMQ\Queue\Jobs\RabbitMQJob; -final class QueueConfig +class QueueConfig { - private string $queue = 'default'; + protected string $queue = 'default'; - private bool $dispatchAfterCommit = false; + protected bool $dispatchAfterCommit = false; - private string $abstractJob = RabbitMQJob::class; + protected string $abstractJob = RabbitMQJob::class; - private bool $prioritizeDelayed = false; + protected bool $prioritizeDelayed = false; - private int $queueMaxPriority = 2; + protected int $queueMaxPriority = 2; - private ?string $exchange = null; + protected ?string $exchange = null; - private string $exchangeType = 'direct'; + protected string $exchangeType = 'direct'; - private string $exchangeRoutingKey = '%s'; + protected string $exchangeRoutingKey = '%s'; - private bool $rerouteFailed = false; + protected bool $rerouteFailed = false; - private ?string $failedExchange = null; + protected ?string $failedExchange = null; - private string $failedRoutingKey = '%s.failed'; + protected string $failedRoutingKey = '%s.failed'; - private bool $quorum = false; + protected bool $quorum = false; - private array $options = []; + protected array $options = []; public function getQueue(): string { diff --git a/src/Queue/QueueConfigFactory.php b/src/Queue/QueueConfigFactory.php index 6266cf20..87fc2fac 100644 --- a/src/Queue/QueueConfigFactory.php +++ b/src/Queue/QueueConfigFactory.php @@ -6,7 +6,7 @@ class QueueConfigFactory { - private const CONFIG_OPTIONS = 'options'; + protected const CONFIG_OPTIONS = 'options'; /** * Create a config object from config array @@ -25,7 +25,7 @@ public static function make(array $config = []): QueueConfig }); } - private static function getOptionsFromConfig(QueueConfig $queueConfig, array $config): void + protected static function getOptionsFromConfig(QueueConfig $queueConfig, array $config): void { $queueOptions = Arr::get($config, self::CONFIG_OPTIONS.'.queue', []) ?: []; From 947ba6aa86029b57a57b61ad9dc53e247ee3e82d Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Thu, 16 Mar 2023 11:54:05 +0100 Subject: [PATCH 057/150] throw test --- tests/Feature/QueueTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Feature/QueueTest.php b/tests/Feature/QueueTest.php index 357d9b01..0f8681fc 100644 --- a/tests/Feature/QueueTest.php +++ b/tests/Feature/QueueTest.php @@ -34,7 +34,8 @@ public function testWithoutReconnect(): void $queue->getConnection()->close(); $this->assertFalse($queue->getConnection()->isConnected()); - $this->assertThrows(fn () => $queue->push(new TestJob()), AMQPChannelClosedException::class); + $this->expectException(AMQPChannelClosedException::class); + $queue->push(new TestJob()); } public function testReconnect(): void From bdbdc42fcf0a17629525b8ebe512e3da4c1dd292 Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Wed, 15 Mar 2023 18:08:43 +0100 Subject: [PATCH 058/150] added tests --- tests/Feature/QueueTest.php | 45 ++++++++++++++++++++++++++ tests/Functional/RabbitMQQueueTest.php | 5 +++ tests/TestCase.php | 20 ++++++++++++ 3 files changed, 70 insertions(+) diff --git a/tests/Feature/QueueTest.php b/tests/Feature/QueueTest.php index 3258b7f2..0f8681fc 100644 --- a/tests/Feature/QueueTest.php +++ b/tests/Feature/QueueTest.php @@ -3,11 +3,56 @@ namespace VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Feature; use PhpAmqpLib\Connection\AMQPStreamConnection; +use PhpAmqpLib\Exception\AMQPChannelClosedException; +use PhpAmqpLib\Exception\AMQPConnectionClosedException; +use PhpAmqpLib\Exception\AMQPProtocolChannelException; +use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Mocks\TestJob; class QueueTest extends TestCase { + public function setUp(): void + { + parent::setUp(); + + $this->withoutExceptionHandling([AMQPChannelClosedException::class, AMQPConnectionClosedException::class, AMQPProtocolChannelException::class]); + } + public function testConnection(): void { $this->assertInstanceOf(AMQPStreamConnection::class, $this->connection()->getChannel()->getConnection()); } + + public function testWithoutReconnect(): void + { + $queue = $this->connection('rabbitmq'); + + $queue->push(new TestJob()); + sleep(1); + $this->assertSame(1, $queue->size()); + + // close connection + $queue->getConnection()->close(); + $this->assertFalse($queue->getConnection()->isConnected()); + + $this->expectException(AMQPChannelClosedException::class); + $queue->push(new TestJob()); + } + + public function testReconnect(): void + { + $queue = $this->connection('octane'); + + $queue->push(new TestJob()); + sleep(1); + $this->assertSame(1, $queue->size()); + + // close connection + $queue->getConnection()->close(); + $this->assertFalse($queue->getConnection()->isConnected()); + + $queue->push(new TestJob()); + sleep(1); + $this->assertTrue($queue->getConnection()->isConnected()); + $this->assertSame(2, $queue->size()); + } } diff --git a/tests/Functional/RabbitMQQueueTest.php b/tests/Functional/RabbitMQQueueTest.php index 5a50342b..fac5e889 100644 --- a/tests/Functional/RabbitMQQueueTest.php +++ b/tests/Functional/RabbitMQQueueTest.php @@ -4,6 +4,7 @@ use Illuminate\Support\Str; use PhpAmqpLib\Exchange\AMQPExchangeType; +use VladimirYuldashev\LaravelQueueRabbitMQ\Octane\RabbitMQQueue as OctaneRabbitMQQueue; use VladimirYuldashev\LaravelQueueRabbitMQ\Queue\RabbitMQQueue; use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Functional\TestCase as BaseTestCase; @@ -19,6 +20,10 @@ public function testConnection(): void $queue = $this->connection('rabbitmq-with-options-empty'); $this->assertInstanceOf(RabbitMQQueue::class, $queue); + + $queue = $this->connection('rabbitmq-with-octane-reconnect-options'); + $this->assertInstanceOf(RabbitMQQueue::class, $queue); + $this->assertInstanceOf(OctaneRabbitMQQueue::class, $queue); } public function testConfigRerouteFailed(): void diff --git a/tests/TestCase.php b/tests/TestCase.php index 7d50fa67..9bea59b3 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -48,6 +48,26 @@ protected function getEnvironmentSetUp($app): void 'worker' => 'default', ]); + $app['config']->set('queue.connections.octane', [ + 'driver' => 'rabbitmq', + 'queue' => 'default', + 'connection' => AMQPLazyConnection::class, + + 'hosts' => [ + [ + 'host' => getenv('HOST'), + 'port' => getenv('PORT'), + 'vhost' => '/', + 'user' => 'guest', + 'password' => 'guest', + ], + ], + + 'options' => [], + + 'worker' => 'octane', + + ]); } protected function connection(string $name = null): RabbitMQQueue From 7897f77654ea0a5dcf1ec43239b88b00f948ba2c Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Thu, 16 Mar 2023 12:18:46 +0100 Subject: [PATCH 059/150] removed unnecessary connection config --- tests/Functional/TestCase.php | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/tests/Functional/TestCase.php b/tests/Functional/TestCase.php index b57fd768..4edc8853 100644 --- a/tests/Functional/TestCase.php +++ b/tests/Functional/TestCase.php @@ -157,24 +157,6 @@ protected function getEnvironmentSetUp($app): void 'worker' => 'default', ]); - $app['config']->set('queue.connections.rabbitmq-with-octane-reconnect-options', [ - 'driver' => 'rabbitmq', - 'queue' => 'default', - 'connection' => 'default', - - 'hosts' => [ - [ - 'host' => getenv('HOST'), - 'port' => getenv('PORT'), - 'vhost' => '/', - 'user' => 'guest', - 'password' => 'guest', - ], - ], - - 'worker' => 'octane', - - ]); } /** From 453c890a9052c5c3d3d8c4d4ba5c052632667beb Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Thu, 16 Mar 2023 13:20:43 +0100 Subject: [PATCH 060/150] fixed: - style testing - style fixing --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 94bfc356..20cf5310 100644 --- a/composer.json +++ b/composer.json @@ -50,9 +50,9 @@ "@test:style", "@test:unit" ], - "test:style": "@php vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php --allow-risky=yes --dry-run --diff --verbose", + "test:style": "@php vendor/bin/pint --test -v", "test:unit": "@php vendor/bin/phpunit", - "fix:style": "@php vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php --allow-risky=yes --diff --verbose" + "fix:style": "@php vendor/bin/pint -v" }, "minimum-stability": "dev", "prefer-stable": true From 5acb1cdc4ca3c46df15fcbe4abc9e6c4bb35a44c Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Thu, 16 Mar 2023 13:28:08 +0100 Subject: [PATCH 061/150] updated ReadMe --- README.md | 153 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 107 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index d425e77b..db71fcb3 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,6 @@ RabbitMQ Queue driver for Laravel [![Latest Stable Version](https://poser.pugx.org/vladimir-yuldashev/laravel-queue-rabbitmq/v/stable?format=flat-square)](https://packagist.org/packages/vladimir-yuldashev/laravel-queue-rabbitmq) [![Build Status](https://github.com/vyuldashev/laravel-queue-rabbitmq/workflows/Tests/badge.svg)](https://github.com/vyuldashev/laravel-queue-rabbitmq/actions) [![Total Downloads](https://poser.pugx.org/vladimir-yuldashev/laravel-queue-rabbitmq/downloads?format=flat-square)](https://packagist.org/packages/vladimir-yuldashev/laravel-queue-rabbitmq) -[![StyleCI](https://styleci.io/repos/14976752/shield)](https://styleci.io/repos/14976752) [![License](https://poser.pugx.org/vladimir-yuldashev/laravel-queue-rabbitmq/license?format=flat-square)](https://packagist.org/packages/vladimir-yuldashev/laravel-queue-rabbitmq) ## Support Policy @@ -24,8 +23,12 @@ composer require vladimir-yuldashev/laravel-queue-rabbitmq The package will automatically register itself. +### Configuration + Add connection to `config/queue.php`: +> This is the minimal config for the rabbitMQ connection/driver to work. + ```php 'connections' => [ // ... @@ -33,9 +36,6 @@ Add connection to `config/queue.php`: 'rabbitmq' => [ 'driver' => 'rabbitmq', - 'queue' => env('RABBITMQ_QUEUE', 'default'), - 'connection' => PhpAmqpLib\Connection\AMQPLazyConnection::class, - 'hosts' => [ [ 'host' => env('RABBITMQ_HOST', '127.0.0.1'), @@ -44,33 +44,17 @@ Add connection to `config/queue.php`: 'password' => env('RABBITMQ_PASSWORD', 'guest'), 'vhost' => env('RABBITMQ_VHOST', '/'), ], + // ... ], - - 'options' => [ - 'ssl_options' => [ - 'cafile' => env('RABBITMQ_SSL_CAFILE', null), - 'local_cert' => env('RABBITMQ_SSL_LOCALCERT', null), - 'local_key' => env('RABBITMQ_SSL_LOCALKEY', null), - 'verify_peer' => env('RABBITMQ_SSL_VERIFY_PEER', true), - 'passphrase' => env('RABBITMQ_SSL_PASSPHRASE', null), - ], - 'queue' => [ - 'job' => VladimirYuldashev\LaravelQueueRabbitMQ\Queue\Jobs\RabbitMQJob::class, - ], - ], - - /* - * Set to "horizon" if you wish to use Laravel Horizon. - */ - 'worker' => env('RABBITMQ_WORKER', 'default'), - 'after_commit' => false, + + // ... ], // ... ], ``` -### Optional Config +### Optional Queue Config Optionally add queue options to the config of a connection. Every queue created for this connection, gets the properties. @@ -164,6 +148,30 @@ by adding extra options. ], ``` +### Horizon support +Starting with 8.0, this package supports [Laravel Horizon](http://horizon.laravel.com) out of the box. Firstly, install +Horizon and then set `RABBITMQ_WORKER` to `horizon`. + +Horizon is depending on events dispatched by the worker. +These events inform Horizon what was done with the message/job. + +This Library supports Horizon, but in the config you have to inform Laravel to use the QueueApi compatible with horizon. + +```php +'connections' => [ + // ... + + 'rabbitmq' => [ + // ... + + /* Set to "horizon" if you wish to use Laravel Horizon. */ + 'worker' => env('RABBITMQ_WORKER', 'default'), + ], + + // ... +], +``` + ### Use your own RabbitMQJob class Sometimes you have to work with messages published by another application. @@ -254,9 +262,74 @@ class RabbitMQJob extends BaseJob } ``` +### Use your own Connection + +You can extend the build-in `PhpAmqpLib\Connection\AMQPStreamConnection::class` +or `PhpAmqpLib\Connection\AMQPSLLConnection::class` and within the connection config, you can define your own class. +When you specify a `connection` key in the config, with your own class name, every connection will use your own class. + +An example for the config: + +```php +'connections' => [ + // ... + + 'rabbitmq' => [ + // ... + + 'connection' = > \App\Queue\Connection\MyRabbitMQConnection::class, + ], + + // ... +], +``` + +### Default Queue + +The connection does use a default queue with value 'default', when no queue is provided by laravel. +It is possible to change te default queue by adding an extra parameter in the connection config. + +```php +'connections' => [ + // ... + + 'rabbitmq' => [ + // ... + + 'queue' => env('RABBITMQ_QUEUE', 'default'), + ], + + // ... +], +``` + +### Heartbeat + +By default, your connection will be created with a heartbeat setting of `0`. +You can alter the heartbeat settings by changing the config. + +```php + +'connections' => [ + // ... + + 'rabbitmq' => [ + // ... + + 'options' => [ + // ... + + 'heartbeat' => 10, + ], + ], + + // ... +], +``` + ### SSL Secure -When u need a secure connection to rabbitMQ server(s). Then this is posible by settitng extra config options. +When u need a secure connection to rabbitMQ server(s). Then this is possible by setting extra config options. ```php 'connections' => [ @@ -283,10 +356,9 @@ When u need a secure connection to rabbitMQ server(s). Then this is posible by s ], ``` -### Lazy Connection +### Events after Database commits -By default, your connection will be created as a lazy connection. -If for some reason you dont want the connection lazy you can turn it off by setting the following config. +To instruct Laravel workers to dispatch events after all database commits are completed. ```php 'connections' => [ @@ -295,32 +367,26 @@ If for some reason you dont want the connection lazy you can turn it off by sett 'rabbitmq' => [ // ... - 'lazy' = > false, + 'after_commit' => true, ], // ... ], ``` -### Heartbeat +### Lazy Connection -By default, your connection will be created with a heartbeat setting of `0`. -You can alter the heartbeat settings by changing the config. +By default, your connection will be created as a lazy connection. +If for some reason you don't want the connection lazy you can turn it off by setting the following config. ```php - 'connections' => [ // ... 'rabbitmq' => [ // ... - 'secure' = > true, - 'options' => [ - // ... - - 'heartbeat' => 10, - ], + 'lazy' = > false, ], // ... @@ -334,11 +400,6 @@ to change anything else. If you do not know how to use the Queue API, please refer to the official Laravel documentation: http://laravel.com/docs/queues -## Laravel Horizon Usage - -Starting with 8.0, this package supports [Laravel Horizon](http://horizon.laravel.com) out of the box. Firstly, install -Horizon and then set `RABBITMQ_WORKER` to `horizon`. - ## Lumen Usage For Lumen usage the service provider should be registered manually as follow in `bootstrap/app.php`: @@ -361,7 +422,7 @@ There are two ways of consuming messages. Setup RabbitMQ using `docker-compose`: ```bash -docker-compose up -d rabbitmq +docker compose up -d ``` To run the test suite you can use the following commands: @@ -378,7 +439,7 @@ composer test:unit ``` If you receive any errors from the style tests, you can automatically fix most, -if not all of the issues with the following command: +if not all the issues with the following command: ```bash composer fix:style From 19b5cbb91db88b330be7a90b13631411052731cd Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Thu, 16 Mar 2023 13:36:09 +0100 Subject: [PATCH 062/150] updated ReadMe --- README.md | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index db71fcb3..09522ba9 100644 --- a/README.md +++ b/README.md @@ -149,7 +149,9 @@ by adding extra options. ``` ### Horizon support -Starting with 8.0, this package supports [Laravel Horizon](http://horizon.laravel.com) out of the box. Firstly, install + +Starting with 8.0, this package supports [Laravel Horizon](https://laravel.com/docs/horizon) out of the box. Firstly, +install Horizon and then set `RABBITMQ_WORKER` to `horizon`. Horizon is depending on events dispatched by the worker. @@ -172,6 +174,30 @@ This Library supports Horizon, but in the config you have to inform Laravel to u ], ``` +### Octane support + +Starting with 13.3.0, this package supports [Laravel Octane](https://laravel.com/docs/octane) out of the box. Firstly, +install +Octane and then set `RABBITMQ_WORKER` to `octane`. + +This Library supports Octane, but in the config you have to inform Laravel to use the QueueApi compatible with octane. + +> Note: don't forget to warm 'rabbitmq' connection in the octane config. +```php +'connections' => [ + // ... + + 'rabbitmq' => [ + // ... + + /* Set to "octane" if you wish to use Laravel Octane. */ + 'worker' => env('RABBITMQ_WORKER', 'default'), + ], + + // ... +], +``` + ### Use your own RabbitMQJob class Sometimes you have to work with messages published by another application. From ce16e57ffaf50255dd243cbf9d9af0b9da074616 Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Thu, 16 Mar 2023 13:40:32 +0100 Subject: [PATCH 063/150] Revert "removed unnecessary connection config" This reverts commit 7897f77654ea0a5dcf1ec43239b88b00f948ba2c. --- tests/Functional/TestCase.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/Functional/TestCase.php b/tests/Functional/TestCase.php index 4edc8853..b57fd768 100644 --- a/tests/Functional/TestCase.php +++ b/tests/Functional/TestCase.php @@ -157,6 +157,24 @@ protected function getEnvironmentSetUp($app): void 'worker' => 'default', ]); + $app['config']->set('queue.connections.rabbitmq-with-octane-reconnect-options', [ + 'driver' => 'rabbitmq', + 'queue' => 'default', + 'connection' => 'default', + + 'hosts' => [ + [ + 'host' => getenv('HOST'), + 'port' => getenv('PORT'), + 'vhost' => '/', + 'user' => 'guest', + 'password' => 'guest', + ], + ], + + 'worker' => 'octane', + + ]); } /** From eefd94befec4659b3df0f34fe9ec047108597384 Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Thu, 16 Mar 2023 13:45:00 +0100 Subject: [PATCH 064/150] really... bump --- tests/Functional/RabbitMQQueueTest.php | 2 +- tests/Functional/TestCase.php | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/tests/Functional/RabbitMQQueueTest.php b/tests/Functional/RabbitMQQueueTest.php index fac5e889..4c1aefab 100644 --- a/tests/Functional/RabbitMQQueueTest.php +++ b/tests/Functional/RabbitMQQueueTest.php @@ -21,7 +21,7 @@ public function testConnection(): void $queue = $this->connection('rabbitmq-with-options-empty'); $this->assertInstanceOf(RabbitMQQueue::class, $queue); - $queue = $this->connection('rabbitmq-with-octane-reconnect-options'); + $queue = $this->connection('rabbitmq-for-octane'); $this->assertInstanceOf(RabbitMQQueue::class, $queue); $this->assertInstanceOf(OctaneRabbitMQQueue::class, $queue); } diff --git a/tests/Functional/TestCase.php b/tests/Functional/TestCase.php index b57fd768..73cb2af2 100644 --- a/tests/Functional/TestCase.php +++ b/tests/Functional/TestCase.php @@ -157,11 +157,8 @@ protected function getEnvironmentSetUp($app): void 'worker' => 'default', ]); - $app['config']->set('queue.connections.rabbitmq-with-octane-reconnect-options', [ + $app['config']->set('queue.connections.rabbitmq-for-octane', [ 'driver' => 'rabbitmq', - 'queue' => 'default', - 'connection' => 'default', - 'hosts' => [ [ 'host' => getenv('HOST'), @@ -171,9 +168,7 @@ protected function getEnvironmentSetUp($app): void 'password' => 'guest', ], ], - 'worker' => 'octane', - ]); } From 08fae3a4f93a9c243c8367101deb4bc80132d60e Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Fri, 17 Mar 2023 17:18:36 +0100 Subject: [PATCH 065/150] refactor getExchangeType() - Prior to PHP 8.0 constant() returned null and an E_WARNING, so default could be set easily. Sinds PHP 8.0 an ERROR exception is thrown. - added a defined() check. --- src/Queue/RabbitMQQueue.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Queue/RabbitMQQueue.php b/src/Queue/RabbitMQQueue.php index 8c67cc6d..8dded6b1 100644 --- a/src/Queue/RabbitMQQueue.php +++ b/src/Queue/RabbitMQQueue.php @@ -640,7 +640,9 @@ protected function getRoutingKey(string $destination): string */ protected function getExchangeType(?string $type = null): string { - return @constant(AMQPExchangeType::class.'::'.Str::upper($type ?: $this->getConfig()->getExchangeType())) ?: AMQPExchangeType::DIRECT; + $constant = AMQPExchangeType::class.'::'.Str::upper($type ?: $this->getConfig()->getExchangeType()); + + return defined($constant) ? constant($constant) : AMQPExchangeType::DIRECT; } /** From 9a900f787823ef11b4b29691a33106c8fe9996ac Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Fri, 17 Mar 2023 17:23:13 +0100 Subject: [PATCH 066/150] altered tests - added null values in testing config - testing defaults - testing logic --- tests/Functional/RabbitMQQueueTest.php | 74 ++++++++++++++++++++++---- tests/Functional/TestCase.php | 40 ++++++++++++++ 2 files changed, 105 insertions(+), 9 deletions(-) diff --git a/tests/Functional/RabbitMQQueueTest.php b/tests/Functional/RabbitMQQueueTest.php index 5a50342b..7a106a08 100644 --- a/tests/Functional/RabbitMQQueueTest.php +++ b/tests/Functional/RabbitMQQueueTest.php @@ -31,6 +31,9 @@ public function testConfigRerouteFailed(): void $queue = $this->connection('rabbitmq-with-options-empty'); $this->assertFalse($this->callProperty($queue, 'config')->isRerouteFailed()); + + $queue = $this->connection('rabbitmq-with-options-null'); + $this->assertFalse($this->callProperty($queue, 'config')->isRerouteFailed()); } public function testConfigPrioritizeDelayed(): void @@ -43,6 +46,9 @@ public function testConfigPrioritizeDelayed(): void $queue = $this->connection('rabbitmq-with-options-empty'); $this->assertFalse($this->callProperty($queue, 'config')->isPrioritizeDelayed()); + + $queue = $this->connection('rabbitmq-with-options-null'); + $this->assertFalse($this->callProperty($queue, 'config')->isPrioritizeDelayed()); } public function testQueueMaxPriority(): void @@ -58,6 +64,10 @@ public function testQueueMaxPriority(): void $queue = $this->connection('rabbitmq-with-options-empty'); $this->assertIsInt($this->callProperty($queue, 'config')->getQueueMaxPriority()); $this->assertSame(2, $this->callProperty($queue, 'config')->getQueueMaxPriority()); + + $queue = $this->connection('rabbitmq-with-options-null'); + $this->assertIsInt($this->callProperty($queue, 'config')->getQueueMaxPriority()); + $this->assertSame(2, $this->callProperty($queue, 'config')->getQueueMaxPriority()); } public function testConfigExchangeType(): void @@ -69,45 +79,78 @@ public function testConfigExchangeType(): void $queue = $this->connection('rabbitmq-with-options'); $this->assertSame(AMQPExchangeType::TOPIC, $this->callMethod($queue, 'getExchangeType')); + $this->assertSame(AMQPExchangeType::DIRECT, $this->callMethod($queue, 'getExchangeType', ['direct'])); $queue = $this->connection('rabbitmq-with-options-empty'); $this->assertSame(AMQPExchangeType::DIRECT, $this->callMethod($queue, 'getExchangeType')); + + $queue = $this->connection('rabbitmq-with-options-null'); + $this->assertSame(AMQPExchangeType::DIRECT, $this->callMethod($queue, 'getExchangeType')); + + //testing an unkown type with a default + $this->callProperty($queue, 'config')->setExchangeType('unknown'); + $this->assertSame(AMQPExchangeType::DIRECT, $this->callMethod($queue, 'getExchangeType')); } public function testExchange(): void { $queue = $this->connection(); $this->assertSame('test', $this->callMethod($queue, 'getExchange', ['test'])); - $this->assertNull($this->callMethod($queue, 'getExchange', [''])); - $this->assertNull($this->callMethod($queue, 'getExchange')); + $this->assertSame('', $this->callMethod($queue, 'getExchange', [''])); + $this->assertSame('', $this->callMethod($queue, 'getExchange', [null])); + $this->assertSame('', $this->callMethod($queue, 'getExchange')); $queue = $this->connection('rabbitmq-with-options'); - $this->assertNotNull($this->callMethod($queue, 'getExchange')); $this->assertSame('application-x', $this->callMethod($queue, 'getExchange')); + $this->assertSame('application-x', $this->callMethod($queue, 'getExchange', [null])); + $this->assertSame('test', $this->callMethod($queue, 'getExchange', ['test'])); + $this->assertSame('', $this->callMethod($queue, 'getExchange', [''])); $queue = $this->connection('rabbitmq-with-options-empty'); - $this->assertNull($this->callMethod($queue, 'getExchange')); + $this->assertSame('', $this->callMethod($queue, 'getExchange')); + $this->assertSame('', $this->callMethod($queue, 'getExchange', [null])); + $this->assertSame('test', $this->callMethod($queue, 'getExchange', ['test'])); + $this->assertSame('', $this->callMethod($queue, 'getExchange', [''])); + + $queue = $this->connection('rabbitmq-with-options-null'); + $this->assertSame('', $this->callMethod($queue, 'getExchange')); + $this->assertSame('', $this->callMethod($queue, 'getExchange', [null])); + $this->assertSame('test', $this->callMethod($queue, 'getExchange', ['test'])); + $this->assertSame('', $this->callMethod($queue, 'getExchange', [''])); } public function testFailedExchange(): void { $queue = $this->connection(); $this->assertSame('test', $this->callMethod($queue, 'getFailedExchange', ['test'])); - $this->assertNull($this->callMethod($queue, 'getExchange', [''])); - $this->assertNull($this->callMethod($queue, 'getFailedExchange')); + $this->assertSame('', $this->callMethod($queue, 'getFailedExchange', [''])); + $this->assertSame('', $this->callMethod($queue, 'getFailedExchange', [null])); + $this->assertSame('', $this->callMethod($queue, 'getFailedExchange')); $queue = $this->connection('rabbitmq-with-options'); - $this->assertNotNull($this->callMethod($queue, 'getFailedExchange')); $this->assertSame('failed-exchange', $this->callMethod($queue, 'getFailedExchange')); + $this->assertSame('failed-exchange', $this->callMethod($queue, 'getFailedExchange', [null])); + $this->assertSame('test', $this->callMethod($queue, 'getFailedExchange', ['test'])); + $this->assertSame('', $this->callMethod($queue, 'getFailedExchange', [''])); $queue = $this->connection('rabbitmq-with-options-empty'); - $this->assertNull($this->callMethod($queue, 'getFailedExchange')); + $this->assertSame('', $this->callMethod($queue, 'getFailedExchange')); + $this->assertSame('', $this->callMethod($queue, 'getFailedExchange', [null])); + $this->assertSame('test', $this->callMethod($queue, 'getFailedExchange', ['test'])); + $this->assertSame('', $this->callMethod($queue, 'getFailedExchange', [''])); + + $queue = $this->connection('rabbitmq-with-options-null'); + $this->assertSame('', $this->callMethod($queue, 'getFailedExchange')); + $this->assertSame('', $this->callMethod($queue, 'getFailedExchange', [null])); + $this->assertSame('test', $this->callMethod($queue, 'getFailedExchange', ['test'])); + $this->assertSame('', $this->callMethod($queue, 'getFailedExchange', [''])); } public function testRoutingKey(): void { $queue = $this->connection(); $this->assertSame('test', $this->callMethod($queue, 'getRoutingKey', ['test'])); + $this->assertSame('test', $this->callMethod($queue, 'getRoutingKey', ['.test'])); $this->assertSame('', $this->callMethod($queue, 'getRoutingKey', [''])); $queue = $this->connection('rabbitmq-with-options'); @@ -115,13 +158,18 @@ public function testRoutingKey(): void $queue = $this->connection('rabbitmq-with-options-empty'); $this->assertSame('test', $this->callMethod($queue, 'getRoutingKey', ['test'])); + + $queue = $this->connection('rabbitmq-with-options-null'); + $this->assertSame('test', $this->callMethod($queue, 'getRoutingKey', ['test'])); + $this->callProperty($queue, 'config')->setExchangeRoutingKey('.an.alternate.routing-key'); + $this->assertSame('an.alternate.routing-key', $this->callMethod($queue, 'getRoutingKey', ['test'])); } public function testFailedRoutingKey(): void { $queue = $this->connection(); - $this->assertSame('test.failed', $this->callMethod($queue, 'getFailedRoutingKey', ['test'])); + $this->assertSame('test.failed', $this->callMethod($queue, 'getFailedRoutingKey', ['.test'])); $this->assertSame('failed', $this->callMethod($queue, 'getFailedRoutingKey', [''])); $queue = $this->connection('rabbitmq-with-options'); @@ -129,6 +177,11 @@ public function testFailedRoutingKey(): void $queue = $this->connection('rabbitmq-with-options-empty'); $this->assertSame('test.failed', $this->callMethod($queue, 'getFailedRoutingKey', ['test'])); + + $queue = $this->connection('rabbitmq-with-options-null'); + $this->assertSame('test.failed', $this->callMethod($queue, 'getFailedRoutingKey', ['test'])); + $this->callProperty($queue, 'config')->setFailedRoutingKey('.an.alternate.routing-key'); + $this->assertSame('an.alternate.routing-key', $this->callMethod($queue, 'getFailedRoutingKey', ['test'])); } public function testConfigQuorum(): void @@ -142,6 +195,9 @@ public function testConfigQuorum(): void $queue = $this->connection('rabbitmq-with-options-empty'); $this->assertFalse($this->callProperty($queue, 'config')->isQuorum()); + $queue = $this->connection('rabbitmq-with-options-null'); + $this->assertFalse($this->callProperty($queue, 'config')->isQuorum()); + $queue = $this->connection('rabbitmq-with-quorum-options'); $this->assertTrue($this->callProperty($queue, 'config')->isQuorum()); } diff --git a/tests/Functional/TestCase.php b/tests/Functional/TestCase.php index 4edc8853..0e0f747d 100644 --- a/tests/Functional/TestCase.php +++ b/tests/Functional/TestCase.php @@ -118,6 +118,46 @@ protected function getEnvironmentSetUp($app): void 'worker' => 'default', + ]); + $app['config']->set('queue.connections.rabbitmq-with-options-null', [ + 'driver' => 'rabbitmq', + 'queue' => 'order', + 'connection' => 'default', + + 'hosts' => [ + [ + 'host' => null, + 'port' => null, + 'vhost' => null, + 'user' => null, + 'password' => null, + ], + ], + + 'options' => [ + 'ssl_options' => [ + 'cafile' => null, + 'local_cert' => null, + 'local_key' => null, + 'verify_peer' => null, + 'passphrase' => null, + ], + + 'queue' => [ + 'prioritize_delayed' => null, + 'queue_max_priority' => null, + 'exchange' => null, + 'exchange_type' => null, + 'exchange_routing_key' => null, + 'reroute_failed' => null, + 'failed_exchange' => null, + 'failed_routing_key' => null, + 'quorum' => null, + ], + ], + + 'worker' => 'default', + ]); $app['config']->set('queue.connections.rabbitmq-with-quorum-options', [ 'driver' => 'rabbitmq', From bf18827d3624c0493949c86fb95dfd428cd31a31 Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Fri, 17 Mar 2023 17:28:37 +0100 Subject: [PATCH 067/150] some extra cleanup --- src/Queue/Connection/ConfigFactory.php | 8 +- src/Queue/QueueConfig.php | 143 ++++++++++++++++++------- src/Queue/RabbitMQQueue.php | 15 ++- 3 files changed, 114 insertions(+), 52 deletions(-) diff --git a/src/Queue/Connection/ConfigFactory.php b/src/Queue/Connection/ConfigFactory.php index 4b8f87a1..c6e24699 100644 --- a/src/Queue/Connection/ConfigFactory.php +++ b/src/Queue/Connection/ConfigFactory.php @@ -20,14 +20,14 @@ public static function make(array $config = []): AMQPConnectionConfig // Set the connection to a Lazy by default $connectionConfig->setIsLazy(! in_array( Arr::get($config, 'lazy') ?? true, - [false, 0, '0', 'false'], + [false, 0, '0', 'false', 'no'], true) ); // Set the connection to unsecure by default $connectionConfig->setIsSecure(in_array( Arr::get($config, 'secure'), - [true, 1, '1', 'true'], + [true, 1, '1', 'true', 'yes'], true) ); @@ -86,8 +86,8 @@ protected static function getHeartbeatFromConfig(AMQPConnectionConfig $connectio { $heartbeat = Arr::get($config, self::CONFIG_OPTIONS.'.heartbeat'); - if (! empty($heartbeat) && is_numeric($heartbeat) && 0 < (int) $heartbeat) { - $connectionConfig->setHeartbeat($heartbeat); + if (is_numeric($heartbeat) && intval($heartbeat) > 0) { + $connectionConfig->setHeartbeat((int) $heartbeat); } } } diff --git a/src/Queue/QueueConfig.php b/src/Queue/QueueConfig.php index b5aea131..e7ec27c4 100644 --- a/src/Queue/QueueConfig.php +++ b/src/Queue/QueueConfig.php @@ -16,7 +16,7 @@ class QueueConfig protected int $queueMaxPriority = 2; - protected ?string $exchange = null; + protected string $exchange = ''; protected string $exchangeType = 'direct'; @@ -24,7 +24,7 @@ class QueueConfig protected bool $rerouteFailed = false; - protected ?string $failedExchange = null; + protected string $failedExchange = ''; protected string $failedRoutingKey = '%s.failed'; @@ -32,18 +32,28 @@ class QueueConfig protected array $options = []; + /** + * Holds the default queue name + * + * When no queue name is provided by laravel queue / workers via the QueueApi method's, + * this value is used to publish messages. + */ public function getQueue(): string { return $this->queue; } - public function setQueue(?string $queue): QueueConfig + public function setQueue(string $queue): QueueConfig { - $this->queue = $queue ?: 'default'; + $this->queue = $queue; return $this; } + /** + * Returns &true; as indication that jobs should be dispatched after all database transactions + * have been committed. + */ public function isDispatchAfterCommit(): bool { return $this->dispatchAfterCommit; @@ -51,37 +61,38 @@ public function isDispatchAfterCommit(): bool public function setDispatchAfterCommit($dispatchAfterCommit): QueueConfig { - $this->dispatchAfterCommit = ! empty($dispatchAfterCommit); - - return $this; - } - - public function getOptions(): array - { - return $this->options; - } - - public function setOptions(?array $options): QueueConfig - { - $this->options = $options ?: []; + $this->dispatchAfterCommit = $this->toBoolean($dispatchAfterCommit); return $this; } + /** + * Get the Job::class to use when processing messages + */ public function getAbstractJob(): string { return $this->abstractJob; } - public function setAbstractJob(?string $abstract): QueueConfig + public function setAbstractJob(string $abstract): QueueConfig { - $this->abstractJob = $abstract ?: RabbitMQJob::class; + $this->abstractJob = $abstract; return $this; } /** * Returns &true;, if delayed messages should be prioritized. + * + * RabbitMQ queues work with the FIFO method. So when there are 10000 messages in the queue and + * the delayed message is put back to the queue (at the end) for further processing the delayed message won´t + * process before all 10000 messages are processed. The same is true for requeueing. + * + * This may not what you desire. + * When you want the message to get processed immediately after the delayed time expires or when requeueing, we can + * use prioritization. + * + * @see[https://www.rabbitmq.com/queues.html#basics] */ public function isPrioritizeDelayed(): bool { @@ -90,7 +101,7 @@ public function isPrioritizeDelayed(): bool public function setPrioritizeDelayed($prioritizeDelayed): QueueConfig { - $this->prioritizeDelayed = ! empty($prioritizeDelayed); + $this->prioritizeDelayed = $this->toBoolean($prioritizeDelayed); return $this; } @@ -109,7 +120,7 @@ public function getQueueMaxPriority(): int public function setQueueMaxPriority($queueMaxPriority): QueueConfig { - if (is_numeric($queueMaxPriority)) { + if (is_numeric($queueMaxPriority) && intval($queueMaxPriority) > 1) { $this->queueMaxPriority = (int) $queueMaxPriority; } @@ -117,43 +128,59 @@ public function setQueueMaxPriority($queueMaxPriority): QueueConfig } /** - * Get the exchange name, or &null; as default value. + * Get the exchange name, or empty string; as default value. + * + * The default exchange is an unnamed pre-declared direct exchange. Usually, an empty string + * is frequently used to indicate it. If you choose default exchange, your message will be delivered + * to a queue with the same name as the routing key. + * With a routing key that is the same as the queue name, every queue is immediately tied to the default exchange. */ - public function getExchange(): ?string + public function getExchange(): string { return $this->exchange; } - public function setExchange(?string $exchange): QueueConfig + public function setExchange(string $exchange): QueueConfig { - $this->exchange = $exchange ?: null; + $this->exchange = $exchange; return $this; } + /** + * Get the exchange type + * + * There are four basic RabbitMQ exchange types in RabbitMQ, each of which uses different parameters + * and bindings to route messages in various ways, These are: 'direct', 'topic', 'fanout', 'headers' + * + * The default type is set as 'direct' + */ public function getExchangeType(): string { return $this->exchangeType; } - public function setExchangeType(?string $exchangeType): QueueConfig + public function setExchangeType(string $exchangeType): QueueConfig { - $this->exchangeType = $exchangeType ?: 'direct'; + $this->exchangeType = $exchangeType; return $this; } /** - * @return string + * Get the routing key when using an exchange other than the direct exchange. + * The routing key is a message attribute taken into account by the exchange when deciding how to route a message. + * + * The default routing-key is the given destination: '%s'. */ - public function getExchangeRoutingKey(): ?string + public function getExchangeRoutingKey(): string { return $this->exchangeRoutingKey; } - public function setExchangeRoutingKey(?string $exchangeRoutingKey): QueueConfig + public function setExchangeRoutingKey(string $exchangeRoutingKey): QueueConfig { - $this->exchangeRoutingKey = $exchangeRoutingKey ?: '%s'; + $this->exchangeRoutingKey = $exchangeRoutingKey; return $this; } @@ -168,39 +195,46 @@ public function isRerouteFailed(): bool public function setRerouteFailed($rerouteFailed): QueueConfig { - $this->rerouteFailed = ! empty($rerouteFailed); + $this->rerouteFailed = $this->toBoolean($rerouteFailed); return $this; } - public function getFailedExchange(): ?string + /** + * Get the exchange name with messages are published against. + * The default exchange is empty, so messages will be published directly to a queue. + */ + public function getFailedExchange(): string { return $this->failedExchange; } - public function setFailedExchange(?string $failedExchange): QueueConfig + public function setFailedExchange(string $failedExchange): QueueConfig { - $this->failedExchange = $failedExchange ?: null; + $this->failedExchange = $failedExchange; return $this; } /** - * Get the routing-key for failed messages - * The default routing-key is the given destination substituted by '.failed'. + * Get the substitution string for failed messages + * The default routing-key is the given destination substituted by '%s.failed'. */ public function getFailedRoutingKey(): string { return $this->failedRoutingKey; } - public function setFailedRoutingKey(?string $failedRoutingKey): QueueConfig + public function setFailedRoutingKey(string $failedRoutingKey): QueueConfig { - $this->failedRoutingKey = $failedRoutingKey ?: '%s.failed'; + $this->failedRoutingKey = $failedRoutingKey; return $this; } + /** + * Returns &true;, if queue is marked or set as quorum queue. + */ public function isQuorum(): bool { return $this->quorum; @@ -208,8 +242,37 @@ public function isQuorum(): bool public function setQuorum($quorum): QueueConfig { - $this->quorum = ! empty($quorum); + $this->quorum = $this->toBoolean($quorum); + + return $this; + } + + /** + * Holds all unknown queue options provided in the connection config + */ + public function getOptions(): array + { + return $this->options; + } + + public function setOptions(array $options): QueueConfig + { + $this->options = $options; return $this; } + + /** + * Filters $value to boolean value + * + * Returns: &true; + * For values: 1, '1', true, 'true', 'yes' + * + * Returns: &false; + * For values: 0, '0', false, 'false', '', null, [] , 'ok', 'no', 'no not a bool', 'yes a bool' + */ + protected function toBoolean($value): bool + { + return filter_var($value, FILTER_VALIDATE_BOOLEAN); + } } diff --git a/src/Queue/RabbitMQQueue.php b/src/Queue/RabbitMQQueue.php index 8dded6b1..519bf8b5 100644 --- a/src/Queue/RabbitMQQueue.php +++ b/src/Queue/RabbitMQQueue.php @@ -594,7 +594,7 @@ protected function getQueueArguments(string $destination): array } if ($this->getConfig()->isRerouteFailed()) { - $arguments['x-dead-letter-exchange'] = $this->getFailedExchange() ?? ''; + $arguments['x-dead-letter-exchange'] = $this->getFailedExchange(); $arguments['x-dead-letter-routing-key'] = $this->getFailedRoutingKey($destination); } @@ -611,7 +611,7 @@ protected function getQueueArguments(string $destination): array protected function getDelayQueueArguments(string $destination, int $ttl): array { return [ - 'x-dead-letter-exchange' => $this->getExchange() ?? '', + 'x-dead-letter-exchange' => $this->getExchange(), 'x-dead-letter-routing-key' => $this->getRoutingKey($destination), 'x-message-ttl' => $ttl, 'x-expires' => $ttl * 2, @@ -619,11 +619,11 @@ protected function getDelayQueueArguments(string $destination, int $ttl): array } /** - * Get the exchange name, or &null; as default value. + * Get the exchange name, or empty string; as default value. */ - protected function getExchange(string $exchange = null): ?string + protected function getExchange(?string $exchange = null): string { - return $exchange ?: $this->getConfig()->getExchange(); + return $exchange ?? $this->getConfig()->getExchange(); } /** @@ -648,9 +648,9 @@ protected function getExchangeType(?string $type = null): string /** * Get the exchange for failed messages. */ - protected function getFailedExchange(string $exchange = null): ?string + protected function getFailedExchange(?string $exchange = null): string { - return $exchange ?: $this->getConfig()->getFailedExchange(); + return $exchange ?? $this->getConfig()->getFailedExchange(); } /** @@ -681,7 +681,6 @@ protected function isQueueDeclared(string $name): bool /** * Declare the destination when necessary. * - * * @throws AMQPProtocolChannelException */ protected function declareDestination(string $destination, ?string $exchange = null, string $exchangeType = AMQPExchangeType::DIRECT): void From fa26c9cefa2aac160713de05a20547553b030c20 Mon Sep 17 00:00:00 2001 From: Emiel Bom <11626777+adm-bome@users.noreply.github.com> Date: Fri, 17 Mar 2023 17:36:18 +0100 Subject: [PATCH 068/150] Update README.md Co-authored-by: Matt Grande --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index db71fcb3..aaff3441 100644 --- a/README.md +++ b/README.md @@ -264,7 +264,7 @@ class RabbitMQJob extends BaseJob ### Use your own Connection -You can extend the build-in `PhpAmqpLib\Connection\AMQPStreamConnection::class` +You can extend the built-in `PhpAmqpLib\Connection\AMQPStreamConnection::class` or `PhpAmqpLib\Connection\AMQPSLLConnection::class` and within the connection config, you can define your own class. When you specify a `connection` key in the config, with your own class name, every connection will use your own class. From a35587d50f86a8825397a9b17d2c9b8caceae248 Mon Sep 17 00:00:00 2001 From: Emiel Bom <11626777+adm-bome@users.noreply.github.com> Date: Fri, 17 Mar 2023 17:36:27 +0100 Subject: [PATCH 069/150] Update README.md Co-authored-by: Matt Grande --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index aaff3441..c9d21614 100644 --- a/README.md +++ b/README.md @@ -329,7 +329,7 @@ You can alter the heartbeat settings by changing the config. ### SSL Secure -When u need a secure connection to rabbitMQ server(s). Then this is possible by setting extra config options. +If you need a secure connection to rabbitMQ server(s), you will need to add these extra config options. ```php 'connections' => [ From 983d53d0fa418026f2ebe35c7826d5e955661b66 Mon Sep 17 00:00:00 2001 From: Emiel Bom <11626777+adm-bome@users.noreply.github.com> Date: Fri, 17 Mar 2023 20:25:42 +0100 Subject: [PATCH 070/150] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index c9d21614..5065e013 100644 --- a/README.md +++ b/README.md @@ -395,8 +395,7 @@ If for some reason you don't want the connection lazy you can turn it off by set ## Laravel Usage -Once you completed the configuration you can use the Laravel Queue API. If you used other queue drivers you do not need -to +Once you completed the configuration you can use the Laravel Queue API. If you used other queue drivers you do not need to change anything else. If you do not know how to use the Queue API, please refer to the official Laravel documentation: http://laravel.com/docs/queues From cb0defca92c9f467dfa70d1d15c0819b85bdfb73 Mon Sep 17 00:00:00 2001 From: Daniil Date: Wed, 22 Mar 2023 03:49:29 +0800 Subject: [PATCH 071/150] Add job example for handling non-json messages from rabbitmq queue --- README.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/README.md b/README.md index 24c25862..e459bf68 100644 --- a/README.md +++ b/README.md @@ -254,6 +254,32 @@ class RabbitMQJob extends BaseJob } ``` +If you want to handle raw message, not in JSON format or without 'job' key in JSON, you should add stub for `getName` method: +```php +getRawBody(); + Log::info($anyMessage); + + $this->delete(); + } + + public function getName() + { + return ''; + } +} +``` + ## Laravel Usage Once you completed the configuration you can use the Laravel Queue API. If you used other queue drivers you do not need to From 5b8508bfaa42a9ad2333980f89b9521b6b8eb2f6 Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Tue, 28 Mar 2023 10:53:14 +0200 Subject: [PATCH 072/150] extracted new channel lines to a method createChannel(). --- src/Queue/RabbitMQQueue.php | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/Queue/RabbitMQQueue.php b/src/Queue/RabbitMQQueue.php index 519bf8b5..72e7c352 100644 --- a/src/Queue/RabbitMQQueue.php +++ b/src/Queue/RabbitMQQueue.php @@ -84,7 +84,7 @@ public function size($queue = null): int } // create a temporary channel, so the main channel will not be closed on exception - $channel = $this->getConnection()->channel(); + $channel = $this->createChannel(); [, $size] = $channel->queue_declare($queue, true); $channel->close(); @@ -277,7 +277,7 @@ public function setConnection(AbstractConnection $connection): RabbitMQQueue public function getChannel($forceNew = false): AMQPChannel { if (! $this->channel || $forceNew) { - $this->channel = $this->getConnection()->channel(); + $this->channel = $this->createChannel(); } return $this->channel; @@ -327,7 +327,7 @@ public function isExchangeExists(string $exchange): bool try { // create a temporary channel, so the main channel will not be closed on exception - $channel = $this->getConnection()->channel(); + $channel = $this->createChannel(); $channel->exchange_declare($exchange, '', true); $channel->close(); @@ -401,7 +401,7 @@ public function isQueueExists(string $name = null): bool { try { // create a temporary channel, so the main channel will not be closed on exception - $channel = $this->getConnection()->channel(); + $channel = $this->createChannel(); $channel->queue_declare($this->getQueue($name), true); $channel->close(); @@ -476,7 +476,7 @@ public function bindQueue(string $queue, string $exchange, string $routingKey = public function purge(string $queue = null): void { // create a temporary channel, so the main channel will not be closed on exception - $channel = $this->getConnection()->channel(); + $channel = $this->createChannel(); $channel->queue_purge($this->getQueue($queue)); $channel->close(); } @@ -733,4 +733,9 @@ protected function publishBatch(): void { $this->getChannel()->publish_batch(); } + + protected function createChannel(): AMQPChannel + { + return $this->getConnection()->channel(); + } } From b43ac849361f0f87d5c851b764827e7b7a2226b4 Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Tue, 28 Mar 2023 12:18:56 +0200 Subject: [PATCH 073/150] Keep track of the declared queues inside RabbitMQ. So we won't check unnecessary times. --- src/Queue/RabbitMQQueue.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Queue/RabbitMQQueue.php b/src/Queue/RabbitMQQueue.php index 72e7c352..47a28eac 100644 --- a/src/Queue/RabbitMQQueue.php +++ b/src/Queue/RabbitMQQueue.php @@ -399,12 +399,20 @@ public function deleteExchange(string $name, bool $unused = false): void */ public function isQueueExists(string $name = null): bool { + $queueName = $this->getQueue($name); + + if ($this->isQueueDeclared($queueName)) { + return true; + } + try { // create a temporary channel, so the main channel will not be closed on exception $channel = $this->createChannel(); - $channel->queue_declare($this->getQueue($name), true); + $channel->queue_declare($queueName, true); $channel->close(); + $this->queues[] = $queueName; + return true; } catch (AMQPProtocolChannelException $exception) { if ($exception->amqp_reply_code === 404) { @@ -451,6 +459,9 @@ public function deleteQueue(string $name, bool $if_unused = false, bool $if_empt return; } + $idx = array_search($name, $this->queues); + unset($this->queues[$idx]); + $this->getChannel()->queue_delete($name, $if_unused, $if_empty); } From 8da5b9d05c67ee0269c1711deb142361fe478416 Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Tue, 28 Mar 2023 17:23:15 +0200 Subject: [PATCH 074/150] Some rework based on PR #528 - issue #460 - rework based on [comment](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/531#issuecomment-1486849841) --- src/Queue/RabbitMQQueue.php | 49 +++++++++++++++++++++++------------- src/Queue/ReconnectTrait.php | 28 ++++++++++++++++++--- 2 files changed, 56 insertions(+), 21 deletions(-) diff --git a/src/Queue/RabbitMQQueue.php b/src/Queue/RabbitMQQueue.php index 07338052..57c23e64 100644 --- a/src/Queue/RabbitMQQueue.php +++ b/src/Queue/RabbitMQQueue.php @@ -183,11 +183,19 @@ public function laterRaw($delay, string $payload, $queue = null, int $attempts = */ public function bulk($jobs, $data = '', $queue = null): void { - foreach ((array) $jobs as $job) { + $this->publishBatch($jobs, $queue, $data); + } + + /** + * @throws AMQPProtocolChannelException + */ + protected function publishBatch($jobs, $data = '', $queue = null): void + { + foreach ($jobs as $job) { $this->bulkRaw($this->createPayload($job, $queue, $data), $queue, ['job' => $job]); } - $this->publishBatch(); + $this->batchPublish(); } /** @@ -274,21 +282,6 @@ public function setConnection(AbstractConnection $connection): RabbitMQQueue return $this; } - public function getChannel($forceNew = false): AMQPChannel - { - if (! $this->channel || $forceNew) { - $this->channel = $this->createChannel(); - } - - return $this->channel; - } - - protected function reconnect() - { - $this->getConnection()->reconnect(); - $this->getChannel(true); - } - /** * Job class to use. * @@ -746,13 +739,33 @@ protected function publishBasic($msg, $exchange = '', $destination = '', $mandat $this->getChannel()->basic_publish($msg, $exchange, $destination, $mandatory, $immediate, $ticket); } - protected function publishBatch(): void + protected function batchPublish(): void { $this->getChannel()->publish_batch(); } + public function getChannel($forceNew = false): AMQPChannel + { + if (! $this->channel || $forceNew) { + $this->channel = $this->createChannel(); + } + + return $this->channel; + } + protected function createChannel(): AMQPChannel { return $this->getConnection()->channel(); } + + /** + * @throws Exception + */ + protected function reconnect(): void + { + // Reconnects using the original connection settings. + $this->getConnection()->reconnect(); + // Create a new main channel because all old channels are removed. + $this->getChannel(true); + } } diff --git a/src/Queue/ReconnectTrait.php b/src/Queue/ReconnectTrait.php index 41ec7395..e88059c5 100644 --- a/src/Queue/ReconnectTrait.php +++ b/src/Queue/ReconnectTrait.php @@ -2,11 +2,16 @@ namespace VladimirYuldashev\LaravelQueueRabbitMQ\Queue; +use Exception; +use PhpAmqpLib\Channel\AMQPChannel; use PhpAmqpLib\Exception\AMQPChannelClosedException; use PhpAmqpLib\Exception\AMQPConnectionClosedException; trait ReconnectTrait { + /** + * @throws Exception + */ protected function publishBasic($msg, $exchange = '', $destination = '', $mandatory = false, $immediate = false, $ticket = null): void { try { @@ -17,13 +22,30 @@ protected function publishBasic($msg, $exchange = '', $destination = '', $mandat } } - protected function publishBatch(): void + /** + * @throws Exception + */ + protected function publishBatch($jobs, $data = '', $queue = null): void { try { - parent::publishBatch(); + parent::publishBatch($jobs, $data, $queue); } catch (AMQPConnectionClosedException|AMQPChannelClosedException) { $this->reconnect(); - parent::publishBatch(); + parent::publishBatch($jobs, $data, $queue); + } + } + + /** + * @throws Exception + */ + protected function createChannel(): AMQPChannel + { + try { + return parent::createChannel(); + } catch (AMQPConnectionClosedException) { + $this->reconnect(); + + return parent::createChannel(); } } } From 46f478082bc021ba2b3c009b870ba6f851cddf3e Mon Sep 17 00:00:00 2001 From: Emiel Bom <11626777+adm-bome@users.noreply.github.com> Date: Wed, 12 Apr 2023 11:38:38 +0200 Subject: [PATCH 075/150] Update CHANGELOG-13x.md Some chagelog lines --- CHANGELOG-13x.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG-13x.md b/CHANGELOG-13x.md index 0631fc9d..d7ee1f60 100644 --- a/CHANGELOG-13x.md +++ b/CHANGELOG-13x.md @@ -4,6 +4,17 @@ All notable changes to this project will be documented in this file. ## [unreleased](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v13.2.0...master) +## [13.3.0](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v13.2.0...13.3.0) + +- Refactor the creation of RabbitMQ Connection and QueueAPI. [#528](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/528) +- Added configuration object as single dependency for RabbitMQQueue in constructor. [#528](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/528) +- Fix method getExchangeType, not throwing an exception. [#528](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/528) +- Separating the apilogic from the actual publishing to RabbitMQ. [#528](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/528) +- Added a reconnect method. [#528](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/528) +- Fix the connection and channel not being fully lazy, when QueueAPI was created. [#528](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/528) +- Keep track of declared queue's within RabbitMQ. [#528](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/528) +- Implemented the 'rest' option to the consumer [#530](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/530) + ## [13.2.0](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v13.1.0...13.2.0) - Compatibility with Laravel 10 [#525](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/525) From 22beb422762349de781b5bb13f56d9202272a4d2 Mon Sep 17 00:00:00 2001 From: Daniil Date: Mon, 17 Apr 2023 22:41:45 +0800 Subject: [PATCH 076/150] Fix wrong conflict resolve --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b45d925c..4a9cf69a 100644 --- a/README.md +++ b/README.md @@ -286,6 +286,7 @@ class RabbitMQJob extends BaseJob return ''; } } +``` ### Use your own Connection From 72d06468e8eb597715c74f4bd976b48a5bcf24f0 Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Tue, 25 Apr 2023 16:13:04 +0200 Subject: [PATCH 077/150] update --- CHANGELOG-13x.md | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/CHANGELOG-13x.md b/CHANGELOG-13x.md index d7ee1f60..e3a88435 100644 --- a/CHANGELOG-13x.md +++ b/CHANGELOG-13x.md @@ -2,18 +2,24 @@ All notable changes to this project will be documented in this file. -## [unreleased](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v13.2.0...master) +## [unreleased](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v13.3.0...master) ## [13.3.0](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v13.2.0...13.3.0) -- Refactor the creation of RabbitMQ Connection and QueueAPI. [#528](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/528) -- Added configuration object as single dependency for RabbitMQQueue in constructor. [#528](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/528) -- Fix method getExchangeType, not throwing an exception. [#528](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/528) -- Separating the apilogic from the actual publishing to RabbitMQ. [#528](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/528) +- Refactor the creation of RabbitMQ Connection and + QueueAPI. [#528](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/528) +- Added configuration object as single dependency for RabbitMQQueue in + constructor. [#528](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/528) +- Fix method getExchangeType, not throwing an + exception. [#528](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/528) +- Separating the api logic from the actual publishing to + RabbitMQ. [#528](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/528) - Added a reconnect method. [#528](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/528) -- Fix the connection and channel not being fully lazy, when QueueAPI was created. [#528](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/528) +- Fix the connection and channel not being fully lazy, when QueueAPI was + created. [#528](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/528) - Keep track of declared queue's within RabbitMQ. [#528](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/528) - Implemented the 'rest' option to the consumer [#530](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/530) +- Added abbility to reconnect to RabbitMQ, by inserting a Trait into own `RabbitMQQueue:class` [#530](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/530) ## [13.2.0](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v13.1.0...13.2.0) @@ -27,7 +33,8 @@ All notable changes to this project will be documented in this file. ## [13.0.1 (2022-09-16)](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v13.0.0...v13.0.1) -- Add $dispatchAfterCommit when running via Horizon [#484](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/484) +- Add $dispatchAfterCommit when running via + Horizon [#484](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/484) ## [13.0.0 (2022-09-15)](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v12.0.1...v13.0.0) From 0d34ba776ab600499aa535960e9a81df9e046d99 Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Tue, 25 Apr 2023 18:00:50 +0200 Subject: [PATCH 078/150] rework --- README.md | 124 +++++++++++++++++++------ src/Octane/RabbitMQQueue.php | 11 --- src/Queue/QueueFactory.php | 5 - src/Queue/ReconnectTrait.php | 51 ---------- tests/Feature/QueueTest.php | 6 +- tests/Functional/RabbitMQQueueTest.php | 5 - tests/Functional/TestCase.php | 13 --- tests/TestCase.php | 20 ---- 8 files changed, 102 insertions(+), 133 deletions(-) delete mode 100644 src/Octane/RabbitMQQueue.php delete mode 100644 src/Queue/ReconnectTrait.php diff --git a/README.md b/README.md index e105dd28..99d21d11 100644 --- a/README.md +++ b/README.md @@ -174,30 +174,6 @@ This Library supports Horizon, but in the config you have to inform Laravel to u ], ``` -### Octane support - -Starting with 13.3.0, this package supports [Laravel Octane](https://laravel.com/docs/octane) out of the box. Firstly, -install -Octane and then set `RABBITMQ_WORKER` to `octane`. - -This Library supports Octane, but in the config you have to inform Laravel to use the QueueApi compatible with octane. - -> Note: don't forget to warm 'rabbitmq' connection in the octane config. -```php -'connections' => [ - // ... - - 'rabbitmq' => [ - // ... - - /* Set to "octane" if you wish to use Laravel Octane. */ - 'worker' => env('RABBITMQ_WORKER', 'default'), - ], - - // ... -], -``` - ### Use your own RabbitMQJob class Sometimes you have to work with messages published by another application. @@ -288,7 +264,9 @@ class RabbitMQJob extends BaseJob } ``` -If you want to handle raw message, not in JSON format or without 'job' key in JSON, you should add stub for `getName` method: +If you want to handle raw message, not in JSON format or without 'job' key in JSON, you should add stub for `getName` +method: + ```php Note: Worker classes **must** extend ``VladimirYuldashev\LaravelQueueRabbitMQ\Queue\RabbitMQQueue`` + +```php +'connections' => [ + // ... + + 'rabbitmq' => [ + // ... + + /* Set to a class if you wish to use your own. */ + 'worker' => \App\Queue\RabbitMQQueue::class, + ], + + // ... +], +``` + +```php + Note: this is not best practice, it is an example. + +```php +reconnect(); + parent::publishBasic($msg, $exchange, $destination, $mandatory, $immediate, $ticket); + } + } + + protected function publishBatch($jobs, $data = '', $queue = null): void + { + try { + parent::publishBatch($jobs, $data, $queue); + } catch (AMQPConnectionClosedException|AMQPChannelClosedException) { + $this->reconnect(); + parent::publishBatch($jobs, $data, $queue); + } + } + + protected function createChannel(): AMQPChannel + { + try { + return parent::createChannel(); + } catch (AMQPConnectionClosedException) { + $this->reconnect(); + return parent::createChannel(); + } + } +} +``` + ### Default Queue The connection does use a default queue with value 'default', when no queue is provided by laravel. @@ -445,10 +510,15 @@ If for some reason you don't want the connection lazy you can turn it off by set ], ``` +### Octane support + +Starting with 13.3.0, this package supports [Laravel Octane](https://laravel.com/docs/octane) out of the box. +Firstly, install Octane and don't forget to warm 'rabbitmq' connection in the octane config. + ## Laravel Usage -Once you completed the configuration you can use the Laravel Queue API. If you used other queue drivers you do not need to -change anything else. If you do not know how to use the Queue API, please refer to the official Laravel +Once you completed the configuration you can use the Laravel Queue API. If you used other queue drivers you do not +need to change anything else. If you do not know how to use the Queue API, please refer to the official Laravel documentation: http://laravel.com/docs/queues ## Lumen Usage diff --git a/src/Octane/RabbitMQQueue.php b/src/Octane/RabbitMQQueue.php deleted file mode 100644 index 9e749efa..00000000 --- a/src/Octane/RabbitMQQueue.php +++ /dev/null @@ -1,11 +0,0 @@ -reconnect(); - parent::publishBasic($msg, $exchange, $destination, $mandatory, $immediate, $ticket); - } - } - - /** - * @throws Exception - */ - protected function publishBatch($jobs, $data = '', $queue = null): void - { - try { - parent::publishBatch($jobs, $data, $queue); - } catch (AMQPConnectionClosedException|AMQPChannelClosedException) { - $this->reconnect(); - parent::publishBatch($jobs, $data, $queue); - } - } - - /** - * @throws Exception - */ - protected function createChannel(): AMQPChannel - { - try { - return parent::createChannel(); - } catch (AMQPConnectionClosedException) { - $this->reconnect(); - - return parent::createChannel(); - } - } -} diff --git a/tests/Feature/QueueTest.php b/tests/Feature/QueueTest.php index 0f8681fc..6418dc51 100644 --- a/tests/Feature/QueueTest.php +++ b/tests/Feature/QueueTest.php @@ -14,7 +14,9 @@ public function setUp(): void { parent::setUp(); - $this->withoutExceptionHandling([AMQPChannelClosedException::class, AMQPConnectionClosedException::class, AMQPProtocolChannelException::class]); + $this->withoutExceptionHandling([ + AMQPChannelClosedException::class, AMQPConnectionClosedException::class, AMQPProtocolChannelException::class, + ]); } public function testConnection(): void @@ -40,6 +42,8 @@ public function testWithoutReconnect(): void public function testReconnect(): void { + $this->markTestSkipped(); + $queue = $this->connection('octane'); $queue->push(new TestJob()); diff --git a/tests/Functional/RabbitMQQueueTest.php b/tests/Functional/RabbitMQQueueTest.php index f68be064..7a106a08 100644 --- a/tests/Functional/RabbitMQQueueTest.php +++ b/tests/Functional/RabbitMQQueueTest.php @@ -4,7 +4,6 @@ use Illuminate\Support\Str; use PhpAmqpLib\Exchange\AMQPExchangeType; -use VladimirYuldashev\LaravelQueueRabbitMQ\Octane\RabbitMQQueue as OctaneRabbitMQQueue; use VladimirYuldashev\LaravelQueueRabbitMQ\Queue\RabbitMQQueue; use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Functional\TestCase as BaseTestCase; @@ -20,10 +19,6 @@ public function testConnection(): void $queue = $this->connection('rabbitmq-with-options-empty'); $this->assertInstanceOf(RabbitMQQueue::class, $queue); - - $queue = $this->connection('rabbitmq-for-octane'); - $this->assertInstanceOf(RabbitMQQueue::class, $queue); - $this->assertInstanceOf(OctaneRabbitMQQueue::class, $queue); } public function testConfigRerouteFailed(): void diff --git a/tests/Functional/TestCase.php b/tests/Functional/TestCase.php index 3a5b56c3..0e0f747d 100644 --- a/tests/Functional/TestCase.php +++ b/tests/Functional/TestCase.php @@ -197,19 +197,6 @@ protected function getEnvironmentSetUp($app): void 'worker' => 'default', ]); - $app['config']->set('queue.connections.rabbitmq-for-octane', [ - 'driver' => 'rabbitmq', - 'hosts' => [ - [ - 'host' => getenv('HOST'), - 'port' => getenv('PORT'), - 'vhost' => '/', - 'user' => 'guest', - 'password' => 'guest', - ], - ], - 'worker' => 'octane', - ]); } /** diff --git a/tests/TestCase.php b/tests/TestCase.php index 9bea59b3..7d50fa67 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -48,26 +48,6 @@ protected function getEnvironmentSetUp($app): void 'worker' => 'default', ]); - $app['config']->set('queue.connections.octane', [ - 'driver' => 'rabbitmq', - 'queue' => 'default', - 'connection' => AMQPLazyConnection::class, - - 'hosts' => [ - [ - 'host' => getenv('HOST'), - 'port' => getenv('PORT'), - 'vhost' => '/', - 'user' => 'guest', - 'password' => 'guest', - ], - ], - - 'options' => [], - - 'worker' => 'octane', - - ]); } protected function connection(string $name = null): RabbitMQQueue From dd6ad6043f5368a78b0c560187246fa26ba477d9 Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Tue, 25 Apr 2023 18:09:54 +0200 Subject: [PATCH 079/150] rework 2 --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 99d21d11..ede88702 100644 --- a/README.md +++ b/README.md @@ -151,8 +151,7 @@ by adding extra options. ### Horizon support Starting with 8.0, this package supports [Laravel Horizon](https://laravel.com/docs/horizon) out of the box. Firstly, -install -Horizon and then set `RABBITMQ_WORKER` to `horizon`. +install Horizon and then set `RABBITMQ_WORKER` to `horizon`. Horizon is depending on events dispatched by the worker. These events inform Horizon what was done with the message/job. @@ -320,7 +319,7 @@ If you want to use your own `RabbitMQQueue::class` this is possible by extending `VladimirYuldashev\LaravelQueueRabbitMQ\Queue\RabbitMQQueue`. and inform laravel to use your class by setting `RABBITMQ_WORKER` to `\App\Queue\RabbitMQQueue::class`. -> Note: Worker classes **must** extend ``VladimirYuldashev\LaravelQueueRabbitMQ\Queue\RabbitMQQueue`` +> Note: Worker classes **must** extend `VladimirYuldashev\LaravelQueueRabbitMQ\Queue\RabbitMQQueue` ```php 'connections' => [ From ee24fb1de42d8e4015bc28e5fa740cacaac4eb3b Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Tue, 25 Apr 2023 18:00:50 +0200 Subject: [PATCH 080/150] rework - removed octane shizzle --- README.md | 127 +++++++++++++++++++------ src/Octane/RabbitMQQueue.php | 11 --- src/Queue/QueueFactory.php | 5 - src/Queue/ReconnectTrait.php | 51 ---------- tests/Feature/QueueTest.php | 6 +- tests/Functional/RabbitMQQueueTest.php | 5 - tests/Functional/TestCase.php | 13 --- tests/TestCase.php | 20 ---- 8 files changed, 103 insertions(+), 135 deletions(-) delete mode 100644 src/Octane/RabbitMQQueue.php delete mode 100644 src/Queue/ReconnectTrait.php diff --git a/README.md b/README.md index e105dd28..abaf3518 100644 --- a/README.md +++ b/README.md @@ -151,8 +151,7 @@ by adding extra options. ### Horizon support Starting with 8.0, this package supports [Laravel Horizon](https://laravel.com/docs/horizon) out of the box. Firstly, -install -Horizon and then set `RABBITMQ_WORKER` to `horizon`. +install Horizon and then set `RABBITMQ_WORKER` to `horizon`. Horizon is depending on events dispatched by the worker. These events inform Horizon what was done with the message/job. @@ -174,30 +173,6 @@ This Library supports Horizon, but in the config you have to inform Laravel to u ], ``` -### Octane support - -Starting with 13.3.0, this package supports [Laravel Octane](https://laravel.com/docs/octane) out of the box. Firstly, -install -Octane and then set `RABBITMQ_WORKER` to `octane`. - -This Library supports Octane, but in the config you have to inform Laravel to use the QueueApi compatible with octane. - -> Note: don't forget to warm 'rabbitmq' connection in the octane config. -```php -'connections' => [ - // ... - - 'rabbitmq' => [ - // ... - - /* Set to "octane" if you wish to use Laravel Octane. */ - 'worker' => env('RABBITMQ_WORKER', 'default'), - ], - - // ... -], -``` - ### Use your own RabbitMQJob class Sometimes you have to work with messages published by another application. @@ -288,7 +263,9 @@ class RabbitMQJob extends BaseJob } ``` -If you want to handle raw message, not in JSON format or without 'job' key in JSON, you should add stub for `getName` method: +If you want to handle raw message, not in JSON format or without 'job' key in JSON, +you should add stub for `getName` method: + ```php Note: Worker classes **must** extend `VladimirYuldashev\LaravelQueueRabbitMQ\Queue\RabbitMQQueue` + +```php +'connections' => [ + // ... + + 'rabbitmq' => [ + // ... + + /* Set to a class if you wish to use your own. */ + 'worker' => \App\Queue\RabbitMQQueue::class, + ], + + // ... +], +``` + +```php + Note: this is not best practice, it is an example. + +```php +reconnect(); + parent::publishBasic($msg, $exchange, $destination, $mandatory, $immediate, $ticket); + } + } + + protected function publishBatch($jobs, $data = '', $queue = null): void + { + try { + parent::publishBatch($jobs, $data, $queue); + } catch (AMQPConnectionClosedException|AMQPChannelClosedException) { + $this->reconnect(); + parent::publishBatch($jobs, $data, $queue); + } + } + + protected function createChannel(): AMQPChannel + { + try { + return parent::createChannel(); + } catch (AMQPConnectionClosedException) { + $this->reconnect(); + return parent::createChannel(); + } + } +} +``` + ### Default Queue The connection does use a default queue with value 'default', when no queue is provided by laravel. @@ -445,10 +509,15 @@ If for some reason you don't want the connection lazy you can turn it off by set ], ``` +### Octane support + +Starting with 13.3.0, this package supports [Laravel Octane](https://laravel.com/docs/octane) out of the box. +Firstly, install Octane and don't forget to warm 'rabbitmq' connection in the octane config. + ## Laravel Usage -Once you completed the configuration you can use the Laravel Queue API. If you used other queue drivers you do not need to -change anything else. If you do not know how to use the Queue API, please refer to the official Laravel +Once you completed the configuration you can use the Laravel Queue API. If you used other queue drivers you do not +need to change anything else. If you do not know how to use the Queue API, please refer to the official Laravel documentation: http://laravel.com/docs/queues ## Lumen Usage diff --git a/src/Octane/RabbitMQQueue.php b/src/Octane/RabbitMQQueue.php deleted file mode 100644 index 9e749efa..00000000 --- a/src/Octane/RabbitMQQueue.php +++ /dev/null @@ -1,11 +0,0 @@ -reconnect(); - parent::publishBasic($msg, $exchange, $destination, $mandatory, $immediate, $ticket); - } - } - - /** - * @throws Exception - */ - protected function publishBatch($jobs, $data = '', $queue = null): void - { - try { - parent::publishBatch($jobs, $data, $queue); - } catch (AMQPConnectionClosedException|AMQPChannelClosedException) { - $this->reconnect(); - parent::publishBatch($jobs, $data, $queue); - } - } - - /** - * @throws Exception - */ - protected function createChannel(): AMQPChannel - { - try { - return parent::createChannel(); - } catch (AMQPConnectionClosedException) { - $this->reconnect(); - - return parent::createChannel(); - } - } -} diff --git a/tests/Feature/QueueTest.php b/tests/Feature/QueueTest.php index 0f8681fc..6418dc51 100644 --- a/tests/Feature/QueueTest.php +++ b/tests/Feature/QueueTest.php @@ -14,7 +14,9 @@ public function setUp(): void { parent::setUp(); - $this->withoutExceptionHandling([AMQPChannelClosedException::class, AMQPConnectionClosedException::class, AMQPProtocolChannelException::class]); + $this->withoutExceptionHandling([ + AMQPChannelClosedException::class, AMQPConnectionClosedException::class, AMQPProtocolChannelException::class, + ]); } public function testConnection(): void @@ -40,6 +42,8 @@ public function testWithoutReconnect(): void public function testReconnect(): void { + $this->markTestSkipped(); + $queue = $this->connection('octane'); $queue->push(new TestJob()); diff --git a/tests/Functional/RabbitMQQueueTest.php b/tests/Functional/RabbitMQQueueTest.php index f68be064..7a106a08 100644 --- a/tests/Functional/RabbitMQQueueTest.php +++ b/tests/Functional/RabbitMQQueueTest.php @@ -4,7 +4,6 @@ use Illuminate\Support\Str; use PhpAmqpLib\Exchange\AMQPExchangeType; -use VladimirYuldashev\LaravelQueueRabbitMQ\Octane\RabbitMQQueue as OctaneRabbitMQQueue; use VladimirYuldashev\LaravelQueueRabbitMQ\Queue\RabbitMQQueue; use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Functional\TestCase as BaseTestCase; @@ -20,10 +19,6 @@ public function testConnection(): void $queue = $this->connection('rabbitmq-with-options-empty'); $this->assertInstanceOf(RabbitMQQueue::class, $queue); - - $queue = $this->connection('rabbitmq-for-octane'); - $this->assertInstanceOf(RabbitMQQueue::class, $queue); - $this->assertInstanceOf(OctaneRabbitMQQueue::class, $queue); } public function testConfigRerouteFailed(): void diff --git a/tests/Functional/TestCase.php b/tests/Functional/TestCase.php index 3a5b56c3..0e0f747d 100644 --- a/tests/Functional/TestCase.php +++ b/tests/Functional/TestCase.php @@ -197,19 +197,6 @@ protected function getEnvironmentSetUp($app): void 'worker' => 'default', ]); - $app['config']->set('queue.connections.rabbitmq-for-octane', [ - 'driver' => 'rabbitmq', - 'hosts' => [ - [ - 'host' => getenv('HOST'), - 'port' => getenv('PORT'), - 'vhost' => '/', - 'user' => 'guest', - 'password' => 'guest', - ], - ], - 'worker' => 'octane', - ]); } /** diff --git a/tests/TestCase.php b/tests/TestCase.php index 9bea59b3..7d50fa67 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -48,26 +48,6 @@ protected function getEnvironmentSetUp($app): void 'worker' => 'default', ]); - $app['config']->set('queue.connections.octane', [ - 'driver' => 'rabbitmq', - 'queue' => 'default', - 'connection' => AMQPLazyConnection::class, - - 'hosts' => [ - [ - 'host' => getenv('HOST'), - 'port' => getenv('PORT'), - 'vhost' => '/', - 'user' => 'guest', - 'password' => 'guest', - ], - ], - - 'options' => [], - - 'worker' => 'octane', - - ]); } protected function connection(string $name = null): RabbitMQQueue From 0c0b396e2a5593e2089ba280ab3217d82ca0daee Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Tue, 25 Apr 2023 18:29:04 +0200 Subject: [PATCH 081/150] update --- CHANGELOG-13x.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG-13x.md b/CHANGELOG-13x.md index e3a88435..88da7e2f 100644 --- a/CHANGELOG-13x.md +++ b/CHANGELOG-13x.md @@ -19,7 +19,8 @@ All notable changes to this project will be documented in this file. created. [#528](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/528) - Keep track of declared queue's within RabbitMQ. [#528](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/528) - Implemented the 'rest' option to the consumer [#530](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/530) -- Added abbility to reconnect to RabbitMQ, by inserting a Trait into own `RabbitMQQueue:class` [#530](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/530) +- Added ability to reconnect to RabbitMQ, by creating your + own `RabbitMQQueue:class` [#531](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/531) ## [13.2.0](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v13.1.0...13.2.0) From 86a1594e9be98ffa03fd722e7298ef797bf9205e Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Wed, 26 Apr 2023 10:44:34 +0200 Subject: [PATCH 082/150] update: warm rabbitmq connection reference --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index abaf3518..edd8d564 100644 --- a/README.md +++ b/README.md @@ -513,6 +513,7 @@ If for some reason you don't want the connection lazy you can turn it off by set Starting with 13.3.0, this package supports [Laravel Octane](https://laravel.com/docs/octane) out of the box. Firstly, install Octane and don't forget to warm 'rabbitmq' connection in the octane config. +> See: https://github.com/vyuldashev/laravel-queue-rabbitmq/issues/460#issuecomment-1469851667 ## Laravel Usage From 826ed957c5fb00790f49d60fbcd53ecd28805775 Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Wed, 26 Apr 2023 14:31:52 +0200 Subject: [PATCH 083/150] update: incorrect use statements in examples --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index edd8d564..8f0081f1 100644 --- a/README.md +++ b/README.md @@ -263,7 +263,7 @@ class RabbitMQJob extends BaseJob } ``` -If you want to handle raw message, not in JSON format or without 'job' key in JSON, +If you want to handle raw message, not in JSON format or without 'job' key in JSON, you should add stub for `getName` method: ```php @@ -342,7 +342,6 @@ and inform laravel to use your class by setting `RABBITMQ_WORKER` to `\App\Queue namespace App\Queue; use VladimirYuldashev\LaravelQueueRabbitMQ\Queue\RabbitMQQueue as BaseRabbitMQQueue; -use VladimirYuldashev\LaravelQueueRabbitMQ\Queue\ReconnectTrait; class RabbitMQQueue extends BaseRabbitMQQueue { @@ -362,8 +361,9 @@ You can override the publishing and the createChannel methods. namespace App\Queue; +use PhpAmqpLib\Exception\AMQPChannelClosedException; +use PhpAmqpLib\Exception\AMQPConnectionClosedException; use VladimirYuldashev\LaravelQueueRabbitMQ\Queue\RabbitMQQueue as BaseRabbitMQQueue; -use VladimirYuldashev\LaravelQueueRabbitMQ\Queue\ReconnectTrait; class RabbitMQQueue extends BaseRabbitMQQueue { From e67d4fc925e5c5d9bdd1b891743181018c9d8218 Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Wed, 26 Apr 2023 17:02:19 +0200 Subject: [PATCH 084/150] update: reconnect tests --- tests/Feature/QueueTest.php | 23 ++--------------------- tests/Functional/TestCase.php | 31 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/tests/Feature/QueueTest.php b/tests/Feature/QueueTest.php index 6418dc51..5ecfb978 100644 --- a/tests/Feature/QueueTest.php +++ b/tests/Feature/QueueTest.php @@ -15,7 +15,8 @@ public function setUp(): void parent::setUp(); $this->withoutExceptionHandling([ - AMQPChannelClosedException::class, AMQPConnectionClosedException::class, AMQPProtocolChannelException::class, + AMQPChannelClosedException::class, AMQPConnectionClosedException::class, + AMQPProtocolChannelException::class, ]); } @@ -39,24 +40,4 @@ public function testWithoutReconnect(): void $this->expectException(AMQPChannelClosedException::class); $queue->push(new TestJob()); } - - public function testReconnect(): void - { - $this->markTestSkipped(); - - $queue = $this->connection('octane'); - - $queue->push(new TestJob()); - sleep(1); - $this->assertSame(1, $queue->size()); - - // close connection - $queue->getConnection()->close(); - $this->assertFalse($queue->getConnection()->isConnected()); - - $queue->push(new TestJob()); - sleep(1); - $this->assertTrue($queue->getConnection()->isConnected()); - $this->assertSame(2, $queue->size()); - } } diff --git a/tests/Functional/TestCase.php b/tests/Functional/TestCase.php index 0e0f747d..a6b7e38f 100644 --- a/tests/Functional/TestCase.php +++ b/tests/Functional/TestCase.php @@ -3,6 +3,7 @@ namespace VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Functional; use Exception; +use PhpAmqpLib\Channel\AMQPChannel; use ReflectionClass; use ReflectionException; use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\TestCase as BaseTestCase; @@ -234,4 +235,34 @@ protected function callProperty($object, string $property): mixed return $property->getValue($object); } + + public function testConnectChannel(): void + { + $queue = $this->connection(); + $this->assertFalse($queue->getConnection()->isConnected()); + + /** @var AMQPChannel $channel */ + $channel = $this->callMethod($queue, 'getChannel'); + $this->assertTrue($queue->getConnection()->isConnected()); + $this->assertSame($channel, $this->callProperty($queue, 'channel')); + $this->assertTrue($channel->is_open()); + } + + public function testReconnect(): void + { + $queue = $this->connection(); + $this->assertFalse($queue->getConnection()->isConnected()); + + // connect + $channel = $this->callMethod($queue, 'getChannel'); + $this->assertTrue($queue->getConnection()->isConnected()); + $this->assertSame($channel, $this->callProperty($queue, 'channel')); + + // reconnect + $queue->getConnection()->close(); + $this->assertFalse($queue->getConnection()->isConnected()); + $this->callMethod($queue, 'reconnect'); + $this->assertTrue($queue->getConnection()->isConnected()); + $this->assertTrue($queue->getChannel()->is_open()); + } } From c1e6d2d177e110e5f3d54a9a851e94df624d089b Mon Sep 17 00:00:00 2001 From: Emiel Bom Date: Wed, 26 Apr 2023 17:07:24 +0200 Subject: [PATCH 085/150] update: reconnect tests --- tests/Functional/TestCase.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/Functional/TestCase.php b/tests/Functional/TestCase.php index a6b7e38f..8b843561 100644 --- a/tests/Functional/TestCase.php +++ b/tests/Functional/TestCase.php @@ -258,9 +258,11 @@ public function testReconnect(): void $this->assertTrue($queue->getConnection()->isConnected()); $this->assertSame($channel, $this->callProperty($queue, 'channel')); - // reconnect + // close $queue->getConnection()->close(); $this->assertFalse($queue->getConnection()->isConnected()); + + // reconnect $this->callMethod($queue, 'reconnect'); $this->assertTrue($queue->getConnection()->isConnected()); $this->assertTrue($queue->getChannel()->is_open()); From 1b9ff657a6d5cb265837c6c8f9c8a621a0ef7765 Mon Sep 17 00:00:00 2001 From: Oleksii Prudkyi Date: Tue, 30 May 2023 07:58:20 +0300 Subject: [PATCH 086/150] fix: crash on accessing $currentJob before initialization --- src/Queue/RabbitMQQueue.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Queue/RabbitMQQueue.php b/src/Queue/RabbitMQQueue.php index 57c23e64..96a803fe 100644 --- a/src/Queue/RabbitMQQueue.php +++ b/src/Queue/RabbitMQQueue.php @@ -577,7 +577,7 @@ protected function getRandomId(): string */ public function close(): void { - if (! $this->currentJob->isDeletedOrReleased()) { + if (isset($this->currentJob) && ! $this->currentJob->isDeletedOrReleased()) { $this->reject($this->currentJob, true); } From c8ca2170807e302e19b06562cee57eac493b90b7 Mon Sep 17 00:00:00 2001 From: Sebastien Armand Date: Thu, 1 Jun 2023 16:29:00 -0700 Subject: [PATCH 087/150] update changelog --- CHANGELOG-13x.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG-13x.md b/CHANGELOG-13x.md index 88da7e2f..64e448ce 100644 --- a/CHANGELOG-13x.md +++ b/CHANGELOG-13x.md @@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file. ## [unreleased](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v13.3.0...master) +## [13.3.1](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v13.3.0...13.3.3) +- Fix a bug when no job / message is available on the queue initially [#543](https://github.com/vyuldashev/laravel-queue-rabbitmq/pull/543) + ## [13.3.0](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v13.2.0...13.3.0) - Refactor the creation of RabbitMQ Connection and From 9051e4716d5aaea2be33a0ce745e5c2b3b7e74ac Mon Sep 17 00:00:00 2001 From: Emiel Bom <11626777+adm-bome@users.noreply.github.com> Date: Wed, 14 Jun 2023 00:50:43 +0200 Subject: [PATCH 088/150] Switched the order of the parameters --- src/Queue/RabbitMQQueue.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Queue/RabbitMQQueue.php b/src/Queue/RabbitMQQueue.php index 96a803fe..cf52eb80 100644 --- a/src/Queue/RabbitMQQueue.php +++ b/src/Queue/RabbitMQQueue.php @@ -183,7 +183,7 @@ public function laterRaw($delay, string $payload, $queue = null, int $attempts = */ public function bulk($jobs, $data = '', $queue = null): void { - $this->publishBatch($jobs, $queue, $data); + $this->publishBatch($jobs, $data, $queue); } /** From f864aa8e128df16e1aab45d76fdd6328ca6c6231 Mon Sep 17 00:00:00 2001 From: Maxime Tassy Date: Fri, 7 Jul 2023 16:43:58 +0200 Subject: [PATCH 089/150] Fix #553, add possibility to define network protocol in config --- README.md | 23 +++++++++++++++++++++++ src/Queue/Connection/ConfigFactory.php | 8 ++++++++ 2 files changed, 31 insertions(+) diff --git a/README.md b/README.md index 8f0081f1..532a2634 100644 --- a/README.md +++ b/README.md @@ -509,6 +509,29 @@ If for some reason you don't want the connection lazy you can turn it off by set ], ``` +### Network Protocol + +By default, the network protocol used for connection is tcp. +If for some reason you want to use another network protocol, you can add the extra value in your config options. + +```php +'connections' => [ + // ... + + 'rabbitmq' => [ + // ... + + 'options' => [ + // ... + + 'network_protocol' => 'network wanted', + ], + ], + + // ... +], +``` + ### Octane support Starting with 13.3.0, this package supports [Laravel Octane](https://laravel.com/docs/octane) out of the box. diff --git a/src/Queue/Connection/ConfigFactory.php b/src/Queue/Connection/ConfigFactory.php index c6e24699..b8dc1bd5 100644 --- a/src/Queue/Connection/ConfigFactory.php +++ b/src/Queue/Connection/ConfigFactory.php @@ -37,6 +37,7 @@ public static function make(array $config = []): AMQPConnectionConfig self::getHostFromConfig($connectionConfig, $config); self::getHeartbeatFromConfig($connectionConfig, $config); + self::getNetworkProtocolFromConfig($connectionConfig, $config); }); } @@ -90,4 +91,11 @@ protected static function getHeartbeatFromConfig(AMQPConnectionConfig $connectio $connectionConfig->setHeartbeat((int) $heartbeat); } } + + protected static function getNetworkProtocolFromConfig(AMQPConnectionConfig $connectionConfig, array $config): void + { + if ($networkProtocol = Arr::get($config, self::CONFIG_OPTIONS.'.network_protocol')) { + $connectionConfig->setNetworkProtocol($networkProtocol); + } + } } From 2129c44c6313fa7a974ca6df240bf7b51cd607a9 Mon Sep 17 00:00:00 2001 From: Seb Date: Tue, 11 Jul 2023 10:47:41 -0700 Subject: [PATCH 090/150] Fix issue where was accessed before initialization --- src/Horizon/RabbitMQQueue.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Horizon/RabbitMQQueue.php b/src/Horizon/RabbitMQQueue.php index e4266a76..894cc24b 100644 --- a/src/Horizon/RabbitMQQueue.php +++ b/src/Horizon/RabbitMQQueue.php @@ -48,7 +48,7 @@ public function push($job, $data = '', $queue = null) */ public function pushRaw($payload, $queue = null, array $options = []): int|string|null { - $payload = (new JobPayload($payload))->prepare($this->lastPushed)->value; + $payload = (new JobPayload($payload))->prepare($this->lastPushed ?? null)->value; return tap(parent::pushRaw($payload, $queue, $options), function () use ($queue, $payload): void { $this->event($this->getQueue($queue), new JobPushed($payload)); From 1da950c93ed30b93ee0477f128a5afbdc35706b4 Mon Sep 17 00:00:00 2001 From: Seb Date: Tue, 11 Jul 2023 10:57:38 -0700 Subject: [PATCH 091/150] like this then --- src/Horizon/RabbitMQQueue.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Horizon/RabbitMQQueue.php b/src/Horizon/RabbitMQQueue.php index 894cc24b..fbd712b4 100644 --- a/src/Horizon/RabbitMQQueue.php +++ b/src/Horizon/RabbitMQQueue.php @@ -18,7 +18,7 @@ class RabbitMQQueue extends BaseRabbitMQQueue /** * The job that last pushed to queue via the "push" method. */ - protected string|object $lastPushed; + protected string|object|null $lastPushed = null; /** * Get the number of queue jobs that are ready to process. @@ -48,7 +48,7 @@ public function push($job, $data = '', $queue = null) */ public function pushRaw($payload, $queue = null, array $options = []): int|string|null { - $payload = (new JobPayload($payload))->prepare($this->lastPushed ?? null)->value; + $payload = (new JobPayload($payload))->prepare($this->lastPushed)->value; return tap(parent::pushRaw($payload, $queue, $options), function () use ($queue, $payload): void { $this->event($this->getQueue($queue), new JobPushed($payload)); From df1b3c3d902bcc631297e8d2b48e39dafe3419aa Mon Sep 17 00:00:00 2001 From: Seb Date: Tue, 11 Jul 2023 11:00:37 -0700 Subject: [PATCH 092/150] like this then --- src/Horizon/RabbitMQQueue.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Horizon/RabbitMQQueue.php b/src/Horizon/RabbitMQQueue.php index fbd712b4..924e4649 100644 --- a/src/Horizon/RabbitMQQueue.php +++ b/src/Horizon/RabbitMQQueue.php @@ -18,7 +18,7 @@ class RabbitMQQueue extends BaseRabbitMQQueue /** * The job that last pushed to queue via the "push" method. */ - protected string|object|null $lastPushed = null; + protected string|object $lastPushed = ''; /** * Get the number of queue jobs that are ready to process. From c63c217202871d5e80973d2c75406661fc543a62 Mon Sep 17 00:00:00 2001 From: Seb Date: Tue, 11 Jul 2023 11:16:42 -0700 Subject: [PATCH 093/150] ending the battle with pint --- src/Horizon/RabbitMQQueue.php | 4 ++-- src/Queue/RabbitMQQueue.php | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Horizon/RabbitMQQueue.php b/src/Horizon/RabbitMQQueue.php index 924e4649..894cc24b 100644 --- a/src/Horizon/RabbitMQQueue.php +++ b/src/Horizon/RabbitMQQueue.php @@ -18,7 +18,7 @@ class RabbitMQQueue extends BaseRabbitMQQueue /** * The job that last pushed to queue via the "push" method. */ - protected string|object $lastPushed = ''; + protected string|object $lastPushed; /** * Get the number of queue jobs that are ready to process. @@ -48,7 +48,7 @@ public function push($job, $data = '', $queue = null) */ public function pushRaw($payload, $queue = null, array $options = []): int|string|null { - $payload = (new JobPayload($payload))->prepare($this->lastPushed)->value; + $payload = (new JobPayload($payload))->prepare($this->lastPushed ?? null)->value; return tap(parent::pushRaw($payload, $queue, $options), function () use ($queue, $payload): void { $this->event($this->getQueue($queue), new JobPushed($payload)); diff --git a/src/Queue/RabbitMQQueue.php b/src/Queue/RabbitMQQueue.php index cf52eb80..f477f7c5 100644 --- a/src/Queue/RabbitMQQueue.php +++ b/src/Queue/RabbitMQQueue.php @@ -631,7 +631,7 @@ protected function getDelayQueueArguments(string $destination, int $ttl): array /** * Get the exchange name, or empty string; as default value. */ - protected function getExchange(?string $exchange = null): string + protected function getExchange(string $exchange = null): string { return $exchange ?? $this->getConfig()->getExchange(); } @@ -648,7 +648,7 @@ protected function getRoutingKey(string $destination): string /** * Get the exchangeType, or AMQPExchangeType::DIRECT as default. */ - protected function getExchangeType(?string $type = null): string + protected function getExchangeType(string $type = null): string { $constant = AMQPExchangeType::class.'::'.Str::upper($type ?: $this->getConfig()->getExchangeType()); @@ -658,7 +658,7 @@ protected function getExchangeType(?string $type = null): string /** * Get the exchange for failed messages. */ - protected function getFailedExchange(?string $exchange = null): string + protected function getFailedExchange(string $exchange = null): string { return $exchange ?? $this->getConfig()->getFailedExchange(); } @@ -693,7 +693,7 @@ protected function isQueueDeclared(string $name): bool * * @throws AMQPProtocolChannelException */ - protected function declareDestination(string $destination, ?string $exchange = null, string $exchangeType = AMQPExchangeType::DIRECT): void + protected function declareDestination(string $destination, string $exchange = null, string $exchangeType = AMQPExchangeType::DIRECT): void { // When an exchange is provided and no exchange is present in RabbitMQ, create an exchange. if ($exchange && ! $this->isExchangeExists($exchange)) { From 2aeeb04db1cb1c3ec051898b2a1b572248cc6c2d Mon Sep 17 00:00:00 2001 From: Maxime Tassy Date: Wed, 12 Jul 2023 09:05:40 +0200 Subject: [PATCH 094/150] Move network_protocol up in the config object and document available protocols --- README.md | 7 ++----- src/Queue/Connection/ConfigFactory.php | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 532a2634..149e7e9c 100644 --- a/README.md +++ b/README.md @@ -513,6 +513,7 @@ If for some reason you don't want the connection lazy you can turn it off by set By default, the network protocol used for connection is tcp. If for some reason you want to use another network protocol, you can add the extra value in your config options. +Available protocols : `tcp`, `ssl`, `tls` ```php 'connections' => [ @@ -521,11 +522,7 @@ If for some reason you want to use another network protocol, you can add the ext 'rabbitmq' => [ // ... - 'options' => [ - // ... - - 'network_protocol' => 'network wanted', - ], + 'network_protocol' => 'tcp', ], // ... diff --git a/src/Queue/Connection/ConfigFactory.php b/src/Queue/Connection/ConfigFactory.php index b8dc1bd5..859a7850 100644 --- a/src/Queue/Connection/ConfigFactory.php +++ b/src/Queue/Connection/ConfigFactory.php @@ -94,7 +94,7 @@ protected static function getHeartbeatFromConfig(AMQPConnectionConfig $connectio protected static function getNetworkProtocolFromConfig(AMQPConnectionConfig $connectionConfig, array $config): void { - if ($networkProtocol = Arr::get($config, self::CONFIG_OPTIONS.'.network_protocol')) { + if ($networkProtocol = Arr::get($config, 'network_protocol')) { $connectionConfig->setNetworkProtocol($networkProtocol); } } From 2542290a11e89d982b8825c9114da009b7bd2c07 Mon Sep 17 00:00:00 2001 From: Seb Date: Fri, 14 Jul 2023 10:07:42 -0700 Subject: [PATCH 095/150] Allow SSL Connections with no peer verification --- src/Queue/Connection/ConfigFactory.php | 3 +- src/Queue/Connection/ConnectionFactory.php | 6 +-- tests/Feature/ConnectorTest.php | 45 ++++++++++++++++++++++ tests/Mocks/TestSSLConnection.php | 14 +++++++ 4 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 tests/Mocks/TestSSLConnection.php diff --git a/src/Queue/Connection/ConfigFactory.php b/src/Queue/Connection/ConfigFactory.php index 859a7850..7783b9cd 100644 --- a/src/Queue/Connection/ConfigFactory.php +++ b/src/Queue/Connection/ConfigFactory.php @@ -75,7 +75,8 @@ protected static function getSLLOptionsFromConfig(AMQPConnectionConfig $connecti if ($key = Arr::get($sslConfig, 'local_key')) { $connectionConfig->setSslKey($key); } - if ($verifyPeer = Arr::get($sslConfig, 'verify_peer')) { + if (Arr::has($sslConfig, 'verify_peer')) { + $verifyPeer = Arr::get($sslConfig, 'verify_peer'); $connectionConfig->setSslVerify($verifyPeer); } if ($passphrase = Arr::get($sslConfig, 'passphrase')) { diff --git a/src/Queue/Connection/ConnectionFactory.php b/src/Queue/Connection/ConnectionFactory.php index df19f223..1d6a46e8 100644 --- a/src/Queue/Connection/ConnectionFactory.php +++ b/src/Queue/Connection/ConnectionFactory.php @@ -200,10 +200,10 @@ protected static function assertSSLConnection($connection): void self::assertExtendedOf($connection, self::CONNECTION_SUB_TYPE_SSL); } - protected static function assertExtendedOf($connection, string $abstract): void + protected static function assertExtendedOf($connection, string $parent): void { - if (! is_subclass_of($connection, $abstract)) { - throw new AMQPLogicException(sprintf('The connection must extend: %s', class_basename($abstract))); + if (! is_subclass_of($connection, $parent) && $connection !== $parent) { + throw new AMQPLogicException(sprintf('The connection must extend: %s', class_basename($parent))); } } diff --git a/tests/Feature/ConnectorTest.php b/tests/Feature/ConnectorTest.php index 3ecede98..d4f62258 100644 --- a/tests/Feature/ConnectorTest.php +++ b/tests/Feature/ConnectorTest.php @@ -3,10 +3,12 @@ namespace VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Feature; use Illuminate\Queue\QueueManager; +use PhpAmqpLib\Connection\AMQPConnectionConfig; use PhpAmqpLib\Connection\AMQPLazyConnection; use PhpAmqpLib\Connection\AMQPSSLConnection; use PhpAmqpLib\Connection\AMQPStreamConnection; use VladimirYuldashev\LaravelQueueRabbitMQ\Queue\RabbitMQQueue; +use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Mocks\TestSSLConnection; class ConnectorTest extends \VladimirYuldashev\LaravelQueueRabbitMQ\Tests\TestCase { @@ -138,4 +140,47 @@ public function testSslConnection(): void $this->assertTrue($connection->getConnection()->isConnected()); $this->assertTrue($connection->getChannel()->is_open()); } + + public function testNoVerificationSslConnection(): void + { + $this->app['config']->set('queue.connections.rabbitmq', [ + 'driver' => 'rabbitmq', + 'queue' => env('RABBITMQ_QUEUE', 'default'), + 'connection' => TestSSLConnection::class, + 'secure' => true, + + 'hosts' => [ + [ + 'host' => getenv('HOST'), + 'port' => getenv('PORT_SSL'), + 'user' => 'guest', + 'password' => 'guest', + 'vhost' => '/', + ], + ], + + 'options' => [ + 'ssl_options' => [ + 'cafile' => getenv('RABBITMQ_SSL_CAFILE'), + 'local_cert' => null, + 'local_key' => null, + 'verify_peer' => false, + 'passphrase' => null, + ], + ], + + 'worker' => env('RABBITMQ_WORKER', 'default'), + ]); + + /** @var QueueManager $queue */ + $queue = $this->app['queue']; + + /** @var RabbitMQQueue $connection */ + $connection = $queue->connection('rabbitmq'); + $this->assertInstanceOf(RabbitMQQueue::class, $connection); + $this->assertInstanceOf(AMQPSSLConnection::class, $connection->getConnection()); + /** @var AMQPConnectionConfig */ + $config = $connection->getConnection()->getConfig(); + $this->assertFalse($config->getSslVerify()); + } } diff --git a/tests/Mocks/TestSSLConnection.php b/tests/Mocks/TestSSLConnection.php new file mode 100644 index 00000000..c1586475 --- /dev/null +++ b/tests/Mocks/TestSSLConnection.php @@ -0,0 +1,14 @@ +config; + } +} From 9ae8cd62d247a1598c1a7eff0924c7d8816f9fbe Mon Sep 17 00:00:00 2001 From: Seb Date: Thu, 28 Sep 2023 09:23:02 -0700 Subject: [PATCH 096/150] explain --- tests/Feature/ConnectorTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Feature/ConnectorTest.php b/tests/Feature/ConnectorTest.php index d4f62258..91660ad2 100644 --- a/tests/Feature/ConnectorTest.php +++ b/tests/Feature/ConnectorTest.php @@ -141,6 +141,7 @@ public function testSslConnection(): void $this->assertTrue($connection->getChannel()->is_open()); } + // Test to validate ssl connection params public function testNoVerificationSslConnection(): void { $this->app['config']->set('queue.connections.rabbitmq', [ From 9e4f32e0b62d38714fe0473adb92d08afc2ac91c Mon Sep 17 00:00:00 2001 From: Seb Date: Thu, 28 Sep 2023 09:26:36 -0700 Subject: [PATCH 097/150] pint --- src/Queue/Connection/ConnectionFactory.php | 2 +- src/Queue/RabbitMQQueue.php | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Queue/Connection/ConnectionFactory.php b/src/Queue/Connection/ConnectionFactory.php index 1d6a46e8..f5ccad0e 100644 --- a/src/Queue/Connection/ConnectionFactory.php +++ b/src/Queue/Connection/ConnectionFactory.php @@ -170,7 +170,7 @@ protected static function getSslOptions(AMQPConnectionConfig $config): array 'ciphers' => $config->getSslCiphers(), 'security_level' => $config->getSslSecurityLevel(), ], static function ($value) { - return null !== $value; + return $value !== null; }); } diff --git a/src/Queue/RabbitMQQueue.php b/src/Queue/RabbitMQQueue.php index f477f7c5..0bf2e608 100644 --- a/src/Queue/RabbitMQQueue.php +++ b/src/Queue/RabbitMQQueue.php @@ -303,8 +303,6 @@ public function getJobClass(): string /** * Gets a queue/destination, by default the queue option set on the connection. - * - * @param null $queue */ public function getQueue($queue = null): string { From d6903405cf1bfa52436e9184777f5d6eb4fc32f1 Mon Sep 17 00:00:00 2001 From: Seb Date: Fri, 29 Sep 2023 16:34:47 -0700 Subject: [PATCH 098/150] fix test --- src/Queue/Connection/ConnectionFactory.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Queue/Connection/ConnectionFactory.php b/src/Queue/Connection/ConnectionFactory.php index f5ccad0e..e6641b95 100644 --- a/src/Queue/Connection/ConnectionFactory.php +++ b/src/Queue/Connection/ConnectionFactory.php @@ -159,9 +159,14 @@ protected static function getReadWriteTimeout(AMQPConnectionConfig $config): flo protected static function getSslOptions(AMQPConnectionConfig $config): array { + $path = null; + if (method_exists($config, 'getSslCaPath')) { + $path = $config->getSslCaPath(); + } + return array_filter([ 'cafile' => $config->getSslCaCert(), - 'capath' => $config->getSslCaPath(), + 'capath' => $path, 'local_cert' => $config->getSslCert(), 'local_pk' => $config->getSslKey(), 'verify_peer' => $config->getSslVerify(), From 2b42641f85283bc42c76c8596e16a201f82ab342 Mon Sep 17 00:00:00 2001 From: Seb Date: Mon, 2 Oct 2023 08:33:41 -0700 Subject: [PATCH 099/150] compatibilities --- src/Queue/Connection/ConnectionFactory.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Queue/Connection/ConnectionFactory.php b/src/Queue/Connection/ConnectionFactory.php index e6641b95..97d7c1a6 100644 --- a/src/Queue/Connection/ConnectionFactory.php +++ b/src/Queue/Connection/ConnectionFactory.php @@ -163,6 +163,10 @@ protected static function getSslOptions(AMQPConnectionConfig $config): array if (method_exists($config, 'getSslCaPath')) { $path = $config->getSslCaPath(); } + $securityLevel = null; + if (method_exists($config, 'getSslSecurityLevel')) { + $securityLevel = $config->getSslSecurityLevel(); + } return array_filter([ 'cafile' => $config->getSslCaCert(), @@ -173,7 +177,7 @@ protected static function getSslOptions(AMQPConnectionConfig $config): array 'verify_peer_name' => $config->getSslVerifyName(), 'passphrase' => $config->getSslPassPhrase(), 'ciphers' => $config->getSslCiphers(), - 'security_level' => $config->getSslSecurityLevel(), + 'security_level' => $securityLevel, ], static function ($value) { return $value !== null; }); From 47ef31e7e77a6d1b65b57423890830ba6518da8d Mon Sep 17 00:00:00 2001 From: Seb Date: Mon, 2 Oct 2023 08:43:11 -0700 Subject: [PATCH 100/150] fix --- src/Queue/Connection/ConnectionFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Queue/Connection/ConnectionFactory.php b/src/Queue/Connection/ConnectionFactory.php index 97d7c1a6..00447332 100644 --- a/src/Queue/Connection/ConnectionFactory.php +++ b/src/Queue/Connection/ConnectionFactory.php @@ -91,7 +91,7 @@ protected static function createSocketConnection($connection, AMQPConnectionConf $config->getVhost(), $config->isInsist(), $config->getLoginMethod(), - $config->getLoginResponse(), + $config->getLoginResponse() ?? null, $config->getLocale(), $config->getReadTimeout(), $config->isKeepalive(), From 07cab330f9caa5667464149dcee05c98f2b00cee Mon Sep 17 00:00:00 2001 From: Seb Date: Mon, 2 Oct 2023 08:46:30 -0700 Subject: [PATCH 101/150] compatibility --- composer.json | 2 +- src/Queue/Connection/ConnectionFactory.php | 15 +++------------ 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/composer.json b/composer.json index 20cf5310..2897c08e 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ "php": "^8.0", "ext-json": "*", "illuminate/queue": "^9.0|^10.0", - "php-amqplib/php-amqplib": "^v3.2" + "php-amqplib/php-amqplib": "^v3.3" }, "require-dev": { "phpunit/phpunit": "^9.3", diff --git a/src/Queue/Connection/ConnectionFactory.php b/src/Queue/Connection/ConnectionFactory.php index 00447332..f5ccad0e 100644 --- a/src/Queue/Connection/ConnectionFactory.php +++ b/src/Queue/Connection/ConnectionFactory.php @@ -91,7 +91,7 @@ protected static function createSocketConnection($connection, AMQPConnectionConf $config->getVhost(), $config->isInsist(), $config->getLoginMethod(), - $config->getLoginResponse() ?? null, + $config->getLoginResponse(), $config->getLocale(), $config->getReadTimeout(), $config->isKeepalive(), @@ -159,25 +159,16 @@ protected static function getReadWriteTimeout(AMQPConnectionConfig $config): flo protected static function getSslOptions(AMQPConnectionConfig $config): array { - $path = null; - if (method_exists($config, 'getSslCaPath')) { - $path = $config->getSslCaPath(); - } - $securityLevel = null; - if (method_exists($config, 'getSslSecurityLevel')) { - $securityLevel = $config->getSslSecurityLevel(); - } - return array_filter([ 'cafile' => $config->getSslCaCert(), - 'capath' => $path, + 'capath' => $config->getSslCaPath(), 'local_cert' => $config->getSslCert(), 'local_pk' => $config->getSslKey(), 'verify_peer' => $config->getSslVerify(), 'verify_peer_name' => $config->getSslVerifyName(), 'passphrase' => $config->getSslPassPhrase(), 'ciphers' => $config->getSslCiphers(), - 'security_level' => $securityLevel, + 'security_level' => $config->getSslSecurityLevel(), ], static function ($value) { return $value !== null; }); From d80c00e9a5e991cf96b979d179ec843476cd8371 Mon Sep 17 00:00:00 2001 From: Seb Date: Mon, 2 Oct 2023 08:51:31 -0700 Subject: [PATCH 102/150] will we get there --- src/Queue/Connection/ConnectionFactory.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Queue/Connection/ConnectionFactory.php b/src/Queue/Connection/ConnectionFactory.php index f5ccad0e..7dd95e99 100644 --- a/src/Queue/Connection/ConnectionFactory.php +++ b/src/Queue/Connection/ConnectionFactory.php @@ -159,6 +159,11 @@ protected static function getReadWriteTimeout(AMQPConnectionConfig $config): flo protected static function getSslOptions(AMQPConnectionConfig $config): array { + $securityLevel = null; + if (method_exists($config, 'getSslSecurityLevel')) { + $securityLevel = $config->getSslSecurityLevel(); + } + return array_filter([ 'cafile' => $config->getSslCaCert(), 'capath' => $config->getSslCaPath(), @@ -168,7 +173,7 @@ protected static function getSslOptions(AMQPConnectionConfig $config): array 'verify_peer_name' => $config->getSslVerifyName(), 'passphrase' => $config->getSslPassPhrase(), 'ciphers' => $config->getSslCiphers(), - 'security_level' => $config->getSslSecurityLevel(), + 'security_level' => $securityLevel, ], static function ($value) { return $value !== null; }); From 1a7339bef56f95731e923e11c5e0f34308310950 Mon Sep 17 00:00:00 2001 From: Seb Date: Mon, 2 Oct 2023 09:36:37 -0700 Subject: [PATCH 103/150] compat --- composer.json | 2 +- src/Queue/Connection/ConnectionFactory.php | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index 2897c08e..7c0cfe9c 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ "php": "^8.0", "ext-json": "*", "illuminate/queue": "^9.0|^10.0", - "php-amqplib/php-amqplib": "^v3.3" + "php-amqplib/php-amqplib": "^v3.4" }, "require-dev": { "phpunit/phpunit": "^9.3", diff --git a/src/Queue/Connection/ConnectionFactory.php b/src/Queue/Connection/ConnectionFactory.php index 7dd95e99..f5ccad0e 100644 --- a/src/Queue/Connection/ConnectionFactory.php +++ b/src/Queue/Connection/ConnectionFactory.php @@ -159,11 +159,6 @@ protected static function getReadWriteTimeout(AMQPConnectionConfig $config): flo protected static function getSslOptions(AMQPConnectionConfig $config): array { - $securityLevel = null; - if (method_exists($config, 'getSslSecurityLevel')) { - $securityLevel = $config->getSslSecurityLevel(); - } - return array_filter([ 'cafile' => $config->getSslCaCert(), 'capath' => $config->getSslCaPath(), @@ -173,7 +168,7 @@ protected static function getSslOptions(AMQPConnectionConfig $config): array 'verify_peer_name' => $config->getSslVerifyName(), 'passphrase' => $config->getSslPassPhrase(), 'ciphers' => $config->getSslCiphers(), - 'security_level' => $securityLevel, + 'security_level' => $config->getSslSecurityLevel(), ], static function ($value) { return $value !== null; }); From 128b0d4620f44b188ff517d6b26d3d8b0f7c1405 Mon Sep 17 00:00:00 2001 From: Seb Date: Mon, 2 Oct 2023 09:39:05 -0700 Subject: [PATCH 104/150] compat --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 7c0cfe9c..83767040 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ "php": "^8.0", "ext-json": "*", "illuminate/queue": "^9.0|^10.0", - "php-amqplib/php-amqplib": "^v3.4" + "php-amqplib/php-amqplib": "^v3.5" }, "require-dev": { "phpunit/phpunit": "^9.3", From 83a089e02b9d5de5b5545a235994938bde9600bd Mon Sep 17 00:00:00 2001 From: Seb Date: Mon, 2 Oct 2023 09:41:36 -0700 Subject: [PATCH 105/150] higher --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 83767040..f487d4e9 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ "php": "^8.0", "ext-json": "*", "illuminate/queue": "^9.0|^10.0", - "php-amqplib/php-amqplib": "^v3.5" + "php-amqplib/php-amqplib": "^v3.5.1" }, "require-dev": { "phpunit/phpunit": "^9.3", From 3669445c8def3554b552bf3659ad8833c481666e Mon Sep 17 00:00:00 2001 From: Seb Date: Mon, 2 Oct 2023 09:50:36 -0700 Subject: [PATCH 106/150] higher --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index f487d4e9..e7167c1a 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ "php": "^8.0", "ext-json": "*", "illuminate/queue": "^9.0|^10.0", - "php-amqplib/php-amqplib": "^v3.5.1" + "php-amqplib/php-amqplib": "^v3.5.2" }, "require-dev": { "phpunit/phpunit": "^9.3", From 57fba78ae1d405c19bb6ae37145f47966282c9e4 Mon Sep 17 00:00:00 2001 From: Emiel Bom <11626777+adm-bome@users.noreply.github.com> Date: Wed, 24 Jan 2024 14:32:45 +0100 Subject: [PATCH 107/150] Ignore errors from nullable_type_declarations Quick fix for the pint tests --- pint.json | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 pint.json diff --git a/pint.json b/pint.json new file mode 100644 index 00000000..751c2203 --- /dev/null +++ b/pint.json @@ -0,0 +1,8 @@ +{ + "preset": "laravel", + "rules": { + "nullable_type_declaration_for_default_null_value": { + "use_nullable_type_declaration": false + } + } +} From 2695f785096f08a8535e16697b6c83c4c65fb4ed Mon Sep 17 00:00:00 2001 From: Emiel Bom <11626777+adm-bome@users.noreply.github.com> Date: Wed, 24 Jan 2024 16:42:06 +0100 Subject: [PATCH 108/150] can't use network_protocol for ssl connections --- src/Queue/Connection/ConnectionFactory.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Queue/Connection/ConnectionFactory.php b/src/Queue/Connection/ConnectionFactory.php index f5ccad0e..f531e761 100644 --- a/src/Queue/Connection/ConnectionFactory.php +++ b/src/Queue/Connection/ConnectionFactory.php @@ -126,7 +126,6 @@ protected static function createStreamConnection($connection, AMQPConnectionConf 'keepalive' => $config->isKeepalive(), 'heartbeat' => $config->getHeartbeat(), ], - $config->getNetworkProtocol(), $config ); } From 1475380174bf8c9183d5490fe737f285a4ddb0ae Mon Sep 17 00:00:00 2001 From: Emiel Bom <11626777+adm-bome@users.noreply.github.com> Date: Wed, 24 Jan 2024 16:51:10 +0100 Subject: [PATCH 109/150] skip test --- tests/Feature/TestCase.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/Feature/TestCase.php b/tests/Feature/TestCase.php index 299e7024..fc69568a 100644 --- a/tests/Feature/TestCase.php +++ b/tests/Feature/TestCase.php @@ -96,6 +96,8 @@ public function testPush(): void public function testPushAfterCommit(): void { + $this->markTestSkipped(); + $transaction = new DatabaseTransactionsManager; $this->app->singleton('db.transactions', function ($app) use ($transaction) { From 806a59d2f5ffd04c3c2a421f9c5fa6d929fc4764 Mon Sep 17 00:00:00 2001 From: Emiel Bom <11626777+adm-bome@users.noreply.github.com> Date: Wed, 24 Jan 2024 16:55:24 +0100 Subject: [PATCH 110/150] Update ConnectorTest.php --- tests/Feature/ConnectorTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/Feature/ConnectorTest.php b/tests/Feature/ConnectorTest.php index 91660ad2..8b8ecd82 100644 --- a/tests/Feature/ConnectorTest.php +++ b/tests/Feature/ConnectorTest.php @@ -144,6 +144,8 @@ public function testSslConnection(): void // Test to validate ssl connection params public function testNoVerificationSslConnection(): void { + $this->markTestSkipped(); + $this->app['config']->set('queue.connections.rabbitmq', [ 'driver' => 'rabbitmq', 'queue' => env('RABBITMQ_QUEUE', 'default'), From 089e72d162b7cb554d80a6ecbb85f0d9b00a8baa Mon Sep 17 00:00:00 2001 From: Emiel Bom <11626777+adm-bome@users.noreply.github.com> Date: Thu, 25 Jan 2024 12:37:47 +0100 Subject: [PATCH 111/150] changed signature method commit between laravel versions 9 and 10, the signature of the method `commit` within the `DatabaseTransactionsManager:class` was changed. --- tests/Feature/TestCase.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/Feature/TestCase.php b/tests/Feature/TestCase.php index fc69568a..c49d8608 100644 --- a/tests/Feature/TestCase.php +++ b/tests/Feature/TestCase.php @@ -96,8 +96,6 @@ public function testPush(): void public function testPushAfterCommit(): void { - $this->markTestSkipped(); - $transaction = new DatabaseTransactionsManager; $this->app->singleton('db.transactions', function ($app) use ($transaction) { @@ -112,7 +110,7 @@ public function testPushAfterCommit(): void $this->assertSame(0, Queue::size()); $this->assertNull(Queue::pop()); - $transaction->commit('FakeDBConnection'); + $transaction->commit('FakeDBConnection', 1, 0); sleep(1); From e04ff6b41e626ef2d0457f7b7154cfe856764d02 Mon Sep 17 00:00:00 2001 From: Emiel Bom <11626777+adm-bome@users.noreply.github.com> Date: Thu, 25 Jan 2024 12:49:33 +0100 Subject: [PATCH 112/150] changed the php-amqplib version to ^3.6 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index e7167c1a..cd2e6898 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ "php": "^8.0", "ext-json": "*", "illuminate/queue": "^9.0|^10.0", - "php-amqplib/php-amqplib": "^v3.5.2" + "php-amqplib/php-amqplib": "^v3.6" }, "require-dev": { "phpunit/phpunit": "^9.3", From a7de79e86fd8e2b802ccd8be99979e7165b1f5a8 Mon Sep 17 00:00:00 2001 From: Emiel Bom <11626777+adm-bome@users.noreply.github.com> Date: Thu, 25 Jan 2024 12:52:43 +0100 Subject: [PATCH 113/150] Update ConnectorTest.php --- tests/Feature/ConnectorTest.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/Feature/ConnectorTest.php b/tests/Feature/ConnectorTest.php index 8b8ecd82..91660ad2 100644 --- a/tests/Feature/ConnectorTest.php +++ b/tests/Feature/ConnectorTest.php @@ -144,8 +144,6 @@ public function testSslConnection(): void // Test to validate ssl connection params public function testNoVerificationSslConnection(): void { - $this->markTestSkipped(); - $this->app['config']->set('queue.connections.rabbitmq', [ 'driver' => 'rabbitmq', 'queue' => env('RABBITMQ_QUEUE', 'default'), From ba4dd0e31af0730240a10992b69e04785d59d616 Mon Sep 17 00:00:00 2001 From: Emiel Bom <11626777+adm-bome@users.noreply.github.com> Date: Fri, 26 Jan 2024 13:15:46 +0100 Subject: [PATCH 114/150] Fix for errors on $currentJob property RabbitMQQueue::$currentJob must not be accessed before initialization Fixes for issue: #572 #555 --- src/Queue/RabbitMQQueue.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Queue/RabbitMQQueue.php b/src/Queue/RabbitMQQueue.php index 0bf2e608..19c4efb2 100644 --- a/src/Queue/RabbitMQQueue.php +++ b/src/Queue/RabbitMQQueue.php @@ -54,7 +54,7 @@ class RabbitMQQueue extends Queue implements QueueContract, RabbitMQQueueContrac /** * Current job being processed. */ - protected RabbitMQJob $currentJob; + protected ?RabbitMQJob $currentJob = null; /** * Holds the Configuration From cfca9419eac07def75c5ca2514e21002deb327fa Mon Sep 17 00:00:00 2001 From: Emiel Bom <11626777+adm-bome@users.noreply.github.com> Date: Mon, 29 Jan 2024 10:08:56 +0100 Subject: [PATCH 115/150] Update README.md Build status icon: link/urls altered --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b7b51350..adb7b2e9 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ RabbitMQ Queue driver for Laravel ====================== [![Latest Stable Version](https://poser.pugx.org/vladimir-yuldashev/laravel-queue-rabbitmq/v/stable?format=flat-square)](https://packagist.org/packages/vladimir-yuldashev/laravel-queue-rabbitmq) -[![Build Status](https://github.com/vyuldashev/laravel-queue-rabbitmq/workflows/Tests/badge.svg)](https://github.com/vyuldashev/laravel-queue-rabbitmq/actions) +[![Build Status](https://github.com/vyuldashev/laravel-queue-rabbitmq/actions/workflows/tests.yml/badge.svg?branch=master)](https://github.com/vyuldashev/laravel-queue-rabbitmq/actions/workflows/tests.yml) [![Total Downloads](https://poser.pugx.org/vladimir-yuldashev/laravel-queue-rabbitmq/downloads?format=flat-square)](https://packagist.org/packages/vladimir-yuldashev/laravel-queue-rabbitmq) [![License](https://poser.pugx.org/vladimir-yuldashev/laravel-queue-rabbitmq/license?format=flat-square)](https://packagist.org/packages/vladimir-yuldashev/laravel-queue-rabbitmq) From 3b23045bb9ad27f5a47267cab34bc99989151e70 Mon Sep 17 00:00:00 2001 From: Seb Date: Tue, 12 Mar 2024 13:07:35 -0700 Subject: [PATCH 116/150] laravel 11 test --- .github/workflows/tests.yml | 2 +- composer.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 37c80375..de605b46 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -15,7 +15,7 @@ jobs: matrix: php: ['8.0', '8.1', '8.2'] stability: ['prefer-lowest', prefer-stable] - laravel: ['^9.0', '^10.0'] + laravel: ['^9.0', '^10.0', '^11.0'] exclude: - php: '8.0' laravel: '^10.0' diff --git a/composer.json b/composer.json index cd2e6898..4e70a3eb 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,7 @@ "require": { "php": "^8.0", "ext-json": "*", - "illuminate/queue": "^9.0|^10.0", + "illuminate/queue": "^9.0|^10.0|^11.0", "php-amqplib/php-amqplib": "^v3.6" }, "require-dev": { From 21b4bc11e602249559de7d656ce6a9335395ef50 Mon Sep 17 00:00:00 2001 From: Seb Date: Tue, 12 Mar 2024 13:10:02 -0700 Subject: [PATCH 117/150] missed one --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 4e70a3eb..5d7d43bd 100644 --- a/composer.json +++ b/composer.json @@ -20,7 +20,7 @@ "laravel/horizon": "^5.0", "orchestra/testbench": "^7.0|^8.0", "laravel/pint": "^1.2", - "laravel/framework": "^9.0|^10.0" + "laravel/framework": "^9.0|^10.0|^11.0" }, "autoload": { "psr-4": { From 5ecbc176686d884b1167a751278fd9816d0a7389 Mon Sep 17 00:00:00 2001 From: Seb Date: Tue, 12 Mar 2024 13:12:01 -0700 Subject: [PATCH 118/150] the matrix --- .github/workflows/tests.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index de605b46..0949eeb0 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -19,6 +19,10 @@ jobs: exclude: - php: '8.0' laravel: '^10.0' + - php: '8.0' + laravel: '^11.0' + - php: '8.1' + laravel: '^11.0' name: 'PHP ${{ matrix.php }} - Laravel: ${{matrix.laravel}} - ${{ matrix.stability }}' From a453471dc98692114c03cb0d945adeadc0ac9869 Mon Sep 17 00:00:00 2001 From: Seb Date: Tue, 12 Mar 2024 13:24:11 -0700 Subject: [PATCH 119/150] orchestra --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 5d7d43bd..b9e327d4 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "phpunit/phpunit": "^9.3", "mockery/mockery": "^1.0", "laravel/horizon": "^5.0", - "orchestra/testbench": "^7.0|^8.0", + "orchestra/testbench": "^7.0|^8.0|^9.0", "laravel/pint": "^1.2", "laravel/framework": "^9.0|^10.0|^11.0" }, From a40b400d4f408eb5d182013d69f74e292aae48a8 Mon Sep 17 00:00:00 2001 From: Seb Date: Wed, 13 Mar 2024 09:41:19 -0700 Subject: [PATCH 120/150] reflop From 261d236242c6b5ce61e9a3a90f482f527d700baf Mon Sep 17 00:00:00 2001 From: Seb Date: Wed, 13 Mar 2024 09:57:08 -0700 Subject: [PATCH 121/150] phpunit --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index b9e327d4..d0ec318a 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "php-amqplib/php-amqplib": "^v3.6" }, "require-dev": { - "phpunit/phpunit": "^9.3", + "phpunit/phpunit": "^9.3 || ^10.5 || ^11.0.1", "mockery/mockery": "^1.0", "laravel/horizon": "^5.0", "orchestra/testbench": "^7.0|^8.0|^9.0", From 4d96f07f91bc088cf66f247821c4d1ff12302fe9 Mon Sep 17 00:00:00 2001 From: Seb Date: Wed, 13 Mar 2024 10:06:05 -0700 Subject: [PATCH 122/150] phpunit --- .github/workflows/tests.yml | 2 +- composer.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0949eeb0..79574284 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -54,4 +54,4 @@ jobs: run: ./vendor/bin/pint --test - name: Execute tests - run: sleep 10 && vendor/bin/phpunit --verbose + run: sleep 10 && vendor/bin/phpunit --debug diff --git a/composer.json b/composer.json index d0ec318a..10480139 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "php-amqplib/php-amqplib": "^v3.6" }, "require-dev": { - "phpunit/phpunit": "^9.3 || ^10.5 || ^11.0.1", + "phpunit/phpunit": "^9.3 || ^10.5 || ^11.0", "mockery/mockery": "^1.0", "laravel/horizon": "^5.0", "orchestra/testbench": "^7.0|^8.0|^9.0", From 7947a32523f9d2c43391ba6d93bdd7294df6c3d8 Mon Sep 17 00:00:00 2001 From: Seb Date: Wed, 13 Mar 2024 10:41:50 -0700 Subject: [PATCH 123/150] phpunit --- .github/workflows/tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 79574284..20254e12 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -14,7 +14,7 @@ jobs: fail-fast: true matrix: php: ['8.0', '8.1', '8.2'] - stability: ['prefer-lowest', prefer-stable] + stability: ['prefer-lowest', 'prefer-stable'] laravel: ['^9.0', '^10.0', '^11.0'] exclude: - php: '8.0' @@ -54,4 +54,4 @@ jobs: run: ./vendor/bin/pint --test - name: Execute tests - run: sleep 10 && vendor/bin/phpunit --debug + run: sleep 10 && (vendor/bin/phpunit --debug || vendor/bin/phpunit --verbose) From 173186643e650b91b6eef609f21330a2c4c8211c Mon Sep 17 00:00:00 2001 From: Seb Date: Wed, 13 Mar 2024 10:46:00 -0700 Subject: [PATCH 124/150] phpunit --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 20254e12..fd06a8b9 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -54,4 +54,4 @@ jobs: run: ./vendor/bin/pint --test - name: Execute tests - run: sleep 10 && (vendor/bin/phpunit --debug || vendor/bin/phpunit --verbose) + run: sleep 10 && vendor/bin/phpunit From 6e78b31b1b5ded11a44de41f227d2eb3ad4018f1 Mon Sep 17 00:00:00 2001 From: Seb Date: Wed, 13 Mar 2024 11:04:55 -0700 Subject: [PATCH 125/150] skip10 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 10480139..37a7aac9 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "php-amqplib/php-amqplib": "^v3.6" }, "require-dev": { - "phpunit/phpunit": "^9.3 || ^10.5 || ^11.0", + "phpunit/phpunit": "^9.3|^11.0", "mockery/mockery": "^1.0", "laravel/horizon": "^5.0", "orchestra/testbench": "^7.0|^8.0|^9.0", From ea5b087b3d9feeba2dc127a7ce6363c3595edfc1 Mon Sep 17 00:00:00 2001 From: Seb Date: Wed, 13 Mar 2024 11:08:28 -0700 Subject: [PATCH 126/150] config format --- phpunit.xml.dist | 48 +++++++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 7e166ab8..57791a39 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,27 +1,25 @@ - - - - src/ - - - - - - - - ./tests/ - - - - - - - - - + + + + + + + + + ./tests/ + + + + + + + + + + + + src/ + + From 3c33cddfb65bf156c310a9f1e86c83d7cf868435 Mon Sep 17 00:00:00 2001 From: Seb Date: Wed, 13 Mar 2024 11:13:53 -0700 Subject: [PATCH 127/150] nogroups --- tests/Feature/SslQueueTest.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/Feature/SslQueueTest.php b/tests/Feature/SslQueueTest.php index 7233ee09..e9c460ea 100644 --- a/tests/Feature/SslQueueTest.php +++ b/tests/Feature/SslQueueTest.php @@ -4,9 +4,6 @@ use PhpAmqpLib\Connection\AMQPSSLConnection; -/** - * @group functional - */ class SslQueueTest extends TestCase { public function setUp(): void From 0391b4155398d5c54ab2cfa5b2c14dbfb404d27f Mon Sep 17 00:00:00 2001 From: Seb Date: Wed, 13 Mar 2024 11:22:02 -0700 Subject: [PATCH 128/150] only keep supported versions --- .github/workflows/tests.yml | 9 +++------ composer.json | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index fd06a8b9..7baac992 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,14 +13,10 @@ jobs: strategy: fail-fast: true matrix: - php: ['8.0', '8.1', '8.2'] + php: ['8.1', '8.2', '8.3'] stability: ['prefer-lowest', 'prefer-stable'] - laravel: ['^9.0', '^10.0', '^11.0'] + laravel: ['^10.0', '^11.0'] exclude: - - php: '8.0' - laravel: '^10.0' - - php: '8.0' - laravel: '^11.0' - php: '8.1' laravel: '^11.0' @@ -54,4 +50,5 @@ jobs: run: ./vendor/bin/pint --test - name: Execute tests + if: run: sleep 10 && vendor/bin/phpunit diff --git a/composer.json b/composer.json index 37a7aac9..0f964596 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "php-amqplib/php-amqplib": "^v3.6" }, "require-dev": { - "phpunit/phpunit": "^9.3|^11.0", + "phpunit/phpunit": "^11.0", "mockery/mockery": "^1.0", "laravel/horizon": "^5.0", "orchestra/testbench": "^7.0|^8.0|^9.0", From 6612effdfcf6cc923982c2781e09e3659e93334f Mon Sep 17 00:00:00 2001 From: Seb Date: Wed, 13 Mar 2024 11:23:10 -0700 Subject: [PATCH 129/150] whoopsie --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 0f964596..a4cb0504 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "php-amqplib/php-amqplib": "^v3.6" }, "require-dev": { - "phpunit/phpunit": "^11.0", + "phpunit/phpunit": "^10.0|^11.0", "mockery/mockery": "^1.0", "laravel/horizon": "^5.0", "orchestra/testbench": "^7.0|^8.0|^9.0", From a4065e24bd33500513785a888f0197c41aeff2e0 Mon Sep 17 00:00:00 2001 From: Seb Date: Wed, 13 Mar 2024 11:28:47 -0700 Subject: [PATCH 130/150] who knows --- composer.json | 2 +- phpunit.xml.dist | 29 +++++++++++++++++++---------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/composer.json b/composer.json index a4cb0504..1a91d725 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,7 @@ "require": { "php": "^8.0", "ext-json": "*", - "illuminate/queue": "^9.0|^10.0|^11.0", + "illuminate/queue": "^10.0|^11.0", "php-amqplib/php-amqplib": "^v3.6" }, "require-dev": { diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 57791a39..5d537691 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,20 +1,29 @@ - - - - - - + ./tests/ - - - - + + + + From 453324a0bcca2c8a781972861f789cb1e0db9eb7 Mon Sep 17 00:00:00 2001 From: Seb Date: Wed, 13 Mar 2024 11:37:08 -0700 Subject: [PATCH 131/150] Happify phpunit --- tests/{TestCase.php => BaseTestCase.php} | 4 ++-- tests/Feature/{TestCase.php => BaseTestCase.php} | 4 ++-- tests/Feature/ConnectorTest.php | 2 +- tests/Feature/QueueTest.php | 2 +- tests/Feature/SslQueueTest.php | 2 +- tests/Functional/{TestCase.php => BaseTestCase.php} | 4 ++-- tests/Functional/RabbitMQQueueTest.php | 1 - 7 files changed, 9 insertions(+), 10 deletions(-) rename tests/{TestCase.php => BaseTestCase.php} (94%) rename tests/Feature/{TestCase.php => BaseTestCase.php} (98%) rename tests/Functional/{TestCase.php => BaseTestCase.php} (98%) diff --git a/tests/TestCase.php b/tests/BaseTestCase.php similarity index 94% rename from tests/TestCase.php rename to tests/BaseTestCase.php index 7d50fa67..a2ad4983 100644 --- a/tests/TestCase.php +++ b/tests/BaseTestCase.php @@ -3,12 +3,12 @@ namespace VladimirYuldashev\LaravelQueueRabbitMQ\Tests; use Illuminate\Support\Facades\Queue; -use Orchestra\Testbench\TestCase as BaseTestCase; +use Orchestra\Testbench\TestCase; use PhpAmqpLib\Connection\AMQPLazyConnection; use VladimirYuldashev\LaravelQueueRabbitMQ\LaravelQueueRabbitMQServiceProvider; use VladimirYuldashev\LaravelQueueRabbitMQ\Queue\RabbitMQQueue; -abstract class TestCase extends BaseTestCase +abstract class BaseTestCase extends TestCase { protected function getPackageProviders($app): array { diff --git a/tests/Feature/TestCase.php b/tests/Feature/BaseTestCase.php similarity index 98% rename from tests/Feature/TestCase.php rename to tests/Feature/BaseTestCase.php index c49d8608..11cedfb1 100644 --- a/tests/Feature/TestCase.php +++ b/tests/Feature/BaseTestCase.php @@ -8,10 +8,10 @@ use PhpAmqpLib\Exception\AMQPProtocolChannelException; use RuntimeException; use VladimirYuldashev\LaravelQueueRabbitMQ\Queue\Jobs\RabbitMQJob; +use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\BaseTestCase as TestCase; use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Mocks\TestJob; -use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\TestCase as BaseTestCase; -abstract class TestCase extends BaseTestCase +abstract class BaseTestCase extends TestCase { /** * @throws AMQPProtocolChannelException diff --git a/tests/Feature/ConnectorTest.php b/tests/Feature/ConnectorTest.php index 91660ad2..263fbd90 100644 --- a/tests/Feature/ConnectorTest.php +++ b/tests/Feature/ConnectorTest.php @@ -10,7 +10,7 @@ use VladimirYuldashev\LaravelQueueRabbitMQ\Queue\RabbitMQQueue; use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Mocks\TestSSLConnection; -class ConnectorTest extends \VladimirYuldashev\LaravelQueueRabbitMQ\Tests\TestCase +class ConnectorTest extends \VladimirYuldashev\LaravelQueueRabbitMQ\Tests\BaseTestCase { public function testLazyConnection(): void { diff --git a/tests/Feature/QueueTest.php b/tests/Feature/QueueTest.php index 5ecfb978..3c5ed540 100644 --- a/tests/Feature/QueueTest.php +++ b/tests/Feature/QueueTest.php @@ -8,7 +8,7 @@ use PhpAmqpLib\Exception\AMQPProtocolChannelException; use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Mocks\TestJob; -class QueueTest extends TestCase +class QueueTest extends BaseTestCase { public function setUp(): void { diff --git a/tests/Feature/SslQueueTest.php b/tests/Feature/SslQueueTest.php index e9c460ea..96383bbc 100644 --- a/tests/Feature/SslQueueTest.php +++ b/tests/Feature/SslQueueTest.php @@ -4,7 +4,7 @@ use PhpAmqpLib\Connection\AMQPSSLConnection; -class SslQueueTest extends TestCase +class SslQueueTest extends BaseTestCase { public function setUp(): void { diff --git a/tests/Functional/TestCase.php b/tests/Functional/BaseTestCase.php similarity index 98% rename from tests/Functional/TestCase.php rename to tests/Functional/BaseTestCase.php index 8b843561..0ab263b8 100644 --- a/tests/Functional/TestCase.php +++ b/tests/Functional/BaseTestCase.php @@ -6,9 +6,9 @@ use PhpAmqpLib\Channel\AMQPChannel; use ReflectionClass; use ReflectionException; -use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\TestCase as BaseTestCase; +use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\BaseTestCase as TestCase; -abstract class TestCase extends BaseTestCase +abstract class BaseTestCase extends TestCase { protected function getEnvironmentSetUp($app): void { diff --git a/tests/Functional/RabbitMQQueueTest.php b/tests/Functional/RabbitMQQueueTest.php index 7a106a08..936857ba 100644 --- a/tests/Functional/RabbitMQQueueTest.php +++ b/tests/Functional/RabbitMQQueueTest.php @@ -5,7 +5,6 @@ use Illuminate\Support\Str; use PhpAmqpLib\Exchange\AMQPExchangeType; use VladimirYuldashev\LaravelQueueRabbitMQ\Queue\RabbitMQQueue; -use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Functional\TestCase as BaseTestCase; class RabbitMQQueueTest extends BaseTestCase { From 74c05cdf72bc8f18b0bb5d8a5d9143c42cc60e66 Mon Sep 17 00:00:00 2001 From: Seb Date: Wed, 13 Mar 2024 11:55:48 -0700 Subject: [PATCH 132/150] Revert "Happify phpunit" This reverts commit 453324a0bcca2c8a781972861f789cb1e0db9eb7. --- tests/Feature/ConnectorTest.php | 2 +- tests/Feature/QueueTest.php | 2 +- tests/Feature/SslQueueTest.php | 2 +- tests/Feature/{BaseTestCase.php => TestCase.php} | 4 ++-- tests/Functional/RabbitMQQueueTest.php | 1 + tests/Functional/{BaseTestCase.php => TestCase.php} | 4 ++-- tests/{BaseTestCase.php => TestCase.php} | 4 ++-- 7 files changed, 10 insertions(+), 9 deletions(-) rename tests/Feature/{BaseTestCase.php => TestCase.php} (98%) rename tests/Functional/{BaseTestCase.php => TestCase.php} (98%) rename tests/{BaseTestCase.php => TestCase.php} (94%) diff --git a/tests/Feature/ConnectorTest.php b/tests/Feature/ConnectorTest.php index 263fbd90..91660ad2 100644 --- a/tests/Feature/ConnectorTest.php +++ b/tests/Feature/ConnectorTest.php @@ -10,7 +10,7 @@ use VladimirYuldashev\LaravelQueueRabbitMQ\Queue\RabbitMQQueue; use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Mocks\TestSSLConnection; -class ConnectorTest extends \VladimirYuldashev\LaravelQueueRabbitMQ\Tests\BaseTestCase +class ConnectorTest extends \VladimirYuldashev\LaravelQueueRabbitMQ\Tests\TestCase { public function testLazyConnection(): void { diff --git a/tests/Feature/QueueTest.php b/tests/Feature/QueueTest.php index 3c5ed540..5ecfb978 100644 --- a/tests/Feature/QueueTest.php +++ b/tests/Feature/QueueTest.php @@ -8,7 +8,7 @@ use PhpAmqpLib\Exception\AMQPProtocolChannelException; use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Mocks\TestJob; -class QueueTest extends BaseTestCase +class QueueTest extends TestCase { public function setUp(): void { diff --git a/tests/Feature/SslQueueTest.php b/tests/Feature/SslQueueTest.php index 96383bbc..e9c460ea 100644 --- a/tests/Feature/SslQueueTest.php +++ b/tests/Feature/SslQueueTest.php @@ -4,7 +4,7 @@ use PhpAmqpLib\Connection\AMQPSSLConnection; -class SslQueueTest extends BaseTestCase +class SslQueueTest extends TestCase { public function setUp(): void { diff --git a/tests/Feature/BaseTestCase.php b/tests/Feature/TestCase.php similarity index 98% rename from tests/Feature/BaseTestCase.php rename to tests/Feature/TestCase.php index 11cedfb1..c49d8608 100644 --- a/tests/Feature/BaseTestCase.php +++ b/tests/Feature/TestCase.php @@ -8,10 +8,10 @@ use PhpAmqpLib\Exception\AMQPProtocolChannelException; use RuntimeException; use VladimirYuldashev\LaravelQueueRabbitMQ\Queue\Jobs\RabbitMQJob; -use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\BaseTestCase as TestCase; use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Mocks\TestJob; +use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\TestCase as BaseTestCase; -abstract class BaseTestCase extends TestCase +abstract class TestCase extends BaseTestCase { /** * @throws AMQPProtocolChannelException diff --git a/tests/Functional/RabbitMQQueueTest.php b/tests/Functional/RabbitMQQueueTest.php index 936857ba..7a106a08 100644 --- a/tests/Functional/RabbitMQQueueTest.php +++ b/tests/Functional/RabbitMQQueueTest.php @@ -5,6 +5,7 @@ use Illuminate\Support\Str; use PhpAmqpLib\Exchange\AMQPExchangeType; use VladimirYuldashev\LaravelQueueRabbitMQ\Queue\RabbitMQQueue; +use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Functional\TestCase as BaseTestCase; class RabbitMQQueueTest extends BaseTestCase { diff --git a/tests/Functional/BaseTestCase.php b/tests/Functional/TestCase.php similarity index 98% rename from tests/Functional/BaseTestCase.php rename to tests/Functional/TestCase.php index 0ab263b8..8b843561 100644 --- a/tests/Functional/BaseTestCase.php +++ b/tests/Functional/TestCase.php @@ -6,9 +6,9 @@ use PhpAmqpLib\Channel\AMQPChannel; use ReflectionClass; use ReflectionException; -use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\BaseTestCase as TestCase; +use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\TestCase as BaseTestCase; -abstract class BaseTestCase extends TestCase +abstract class TestCase extends BaseTestCase { protected function getEnvironmentSetUp($app): void { diff --git a/tests/BaseTestCase.php b/tests/TestCase.php similarity index 94% rename from tests/BaseTestCase.php rename to tests/TestCase.php index a2ad4983..7d50fa67 100644 --- a/tests/BaseTestCase.php +++ b/tests/TestCase.php @@ -3,12 +3,12 @@ namespace VladimirYuldashev\LaravelQueueRabbitMQ\Tests; use Illuminate\Support\Facades\Queue; -use Orchestra\Testbench\TestCase; +use Orchestra\Testbench\TestCase as BaseTestCase; use PhpAmqpLib\Connection\AMQPLazyConnection; use VladimirYuldashev\LaravelQueueRabbitMQ\LaravelQueueRabbitMQServiceProvider; use VladimirYuldashev\LaravelQueueRabbitMQ\Queue\RabbitMQQueue; -abstract class BaseTestCase extends TestCase +abstract class TestCase extends BaseTestCase { protected function getPackageProviders($app): array { From 2408bba9f11f20dc07252584a6efeea5a0dfed64 Mon Sep 17 00:00:00 2001 From: Seb Date: Wed, 13 Mar 2024 11:57:36 -0700 Subject: [PATCH 133/150] only use test files --- phpunit.xml.dist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 5d537691..da6c9d37 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -12,7 +12,7 @@ backupStaticProperties="false"> - ./tests/ + ./tests/ From 75fa317e65f2889eca617b7c589dbfd276d95a69 Mon Sep 17 00:00:00 2001 From: Seb Date: Wed, 13 Mar 2024 12:13:31 -0700 Subject: [PATCH 134/150] yo --- phpunit.xml.dist | 57 +++++++++++++++++++++--------------------------- 1 file changed, 25 insertions(+), 32 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index da6c9d37..c3fc3599 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,34 +1,27 @@ - - - - ./tests/ - - - - - - - - - - - - src/ - - + + + + src/ + + + + + + + + ./tests/ + + + + + + + + + From dd97e4b3cb30b2f3260fec12f177f8dfb93ffb40 Mon Sep 17 00:00:00 2001 From: Seb Date: Wed, 13 Mar 2024 12:16:30 -0700 Subject: [PATCH 135/150] fixie --- phpunit.xml.dist | 48 +++++++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index c3fc3599..219f4c66 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,27 +1,25 @@ - - - - src/ - - - - - - - - ./tests/ - - - - - - - - - + + + + + + + + + ./tests/ + + + + + + + + + + + + src/ + + From 3f8df65433a1bda50a0b6f7077e858e4523a6861 Mon Sep 17 00:00:00 2001 From: Seb Date: Wed, 13 Mar 2024 12:19:13 -0700 Subject: [PATCH 136/150] nocov --- phpunit.xml.dist | 5 ----- 1 file changed, 5 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 219f4c66..10a342a9 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,10 +1,5 @@ - - - - - ./tests/ From f550805d944bf130a9e607e0eb061de0b2f38cab Mon Sep 17 00:00:00 2001 From: Seb Date: Wed, 13 Mar 2024 12:21:36 -0700 Subject: [PATCH 137/150] nosource --- phpunit.xml.dist | 5 ----- 1 file changed, 5 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 10a342a9..71be4e98 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -12,9 +12,4 @@ - - - src/ - - From 83c646ea55f7350d1549a107e39230371c547055 Mon Sep 17 00:00:00 2001 From: Seb Date: Wed, 13 Mar 2024 12:26:41 -0700 Subject: [PATCH 138/150] mew --- .github/workflows/tests.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7baac992..fccb0608 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -50,5 +50,4 @@ jobs: run: ./vendor/bin/pint --test - name: Execute tests - if: run: sleep 10 && vendor/bin/phpunit From f87aa9d63b39eb9fb14433f29f2a05db5eb35e4c Mon Sep 17 00:00:00 2001 From: Seb Date: Thu, 14 Mar 2024 08:29:16 -0700 Subject: [PATCH 139/150] changelog --- CHANGELOG-14x.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 CHANGELOG-14x.md diff --git a/CHANGELOG-14x.md b/CHANGELOG-14x.md new file mode 100644 index 00000000..c94b3dd2 --- /dev/null +++ b/CHANGELOG-14x.md @@ -0,0 +1,8 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +## [unreleased](https://github.com/vyuldashev/laravel-queue-rabbitmq/compare/v13.3.0...master) + +## [14.0.0] +- First release compatible with Laravel 11 From fc341b3f19496bc1c66cd38a665c2d2da8b8baaf Mon Sep 17 00:00:00 2001 From: therecluse26 <8239106+therecluse26@users.noreply.github.com> Date: Sun, 21 Apr 2024 15:26:25 -0400 Subject: [PATCH 140/150] Allow for encrypted command data Added a bugfix to handle fetching priority from encrypted command data if the job class implements `ShouldBeEncrypted` --- src/Queue/RabbitMQQueue.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Queue/RabbitMQQueue.php b/src/Queue/RabbitMQQueue.php index 19c4efb2..6cb2126f 100644 --- a/src/Queue/RabbitMQQueue.php +++ b/src/Queue/RabbitMQQueue.php @@ -525,6 +525,11 @@ protected function createMessage($payload, int $attempts = 0): array } if (isset($currentPayload['data']['command'])) { + // If the command data is encrypted, decrypt it first before attempting to unserialize + if (in_array(ShouldBeEncrypted::class, class_implements($currentPayload['data']['commandName']))) { + $currentPayload['data']['command'] = decrypt($currentPayload['data']['command']); + } + $commandData = unserialize($currentPayload['data']['command']); if (property_exists($commandData, 'priority')) { $properties['priority'] = $commandData->priority; From 9bd427a6d281d6e0f0fa576ae04435100380b4dd Mon Sep 17 00:00:00 2001 From: therecluse26 Date: Wed, 24 Apr 2024 17:28:09 -0400 Subject: [PATCH 141/150] Added encryption key, tests and requested updates --- phpunit.xml.dist | 1 + src/Queue/RabbitMQQueue.php | 8 ++- tests/Feature/TestCase.php | 98 ++++++++++++++++++++++++++++++++ tests/Mocks/TestEncryptedJob.php | 25 ++++++++ 4 files changed, 129 insertions(+), 3 deletions(-) create mode 100644 tests/Mocks/TestEncryptedJob.php diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 71be4e98..d213fd63 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -10,6 +10,7 @@ + diff --git a/src/Queue/RabbitMQQueue.php b/src/Queue/RabbitMQQueue.php index 6cb2126f..ce63494d 100644 --- a/src/Queue/RabbitMQQueue.php +++ b/src/Queue/RabbitMQQueue.php @@ -7,8 +7,10 @@ use ErrorException; use Exception; use Illuminate\Contracts\Queue\Queue as QueueContract; +use Illuminate\Contracts\Queue\ShouldBeEncrypted; use Illuminate\Queue\Queue; use Illuminate\Support\Arr; +use Illuminate\Support\Facades\Crypt; use Illuminate\Support\Str; use PhpAmqpLib\Channel\AMQPChannel; use PhpAmqpLib\Connection\AbstractConnection; @@ -526,10 +528,10 @@ protected function createMessage($payload, int $attempts = 0): array if (isset($currentPayload['data']['command'])) { // If the command data is encrypted, decrypt it first before attempting to unserialize - if (in_array(ShouldBeEncrypted::class, class_implements($currentPayload['data']['commandName']))) { - $currentPayload['data']['command'] = decrypt($currentPayload['data']['command']); + if (is_subclass_of($currentPayload['data']['commandName'], ShouldBeEncrypted::class)) { + $currentPayload['data']['command'] = Crypt::decrypt($currentPayload['data']['command']); } - + $commandData = unserialize($currentPayload['data']['command']); if (property_exists($commandData, 'priority')) { $properties['priority'] = $commandData->priority; diff --git a/tests/Feature/TestCase.php b/tests/Feature/TestCase.php index c49d8608..16fd5faa 100644 --- a/tests/Feature/TestCase.php +++ b/tests/Feature/TestCase.php @@ -8,6 +8,7 @@ use PhpAmqpLib\Exception\AMQPProtocolChannelException; use RuntimeException; use VladimirYuldashev\LaravelQueueRabbitMQ\Queue\Jobs\RabbitMQJob; +use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Mocks\TestEncryptedJob; use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Mocks\TestJob; use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\TestCase as BaseTestCase; @@ -194,6 +195,103 @@ public function testBulk(): void $this->assertSame($count, Queue::size()); } + public function testPushEncrypted(): void + { + Queue::push(new TestEncryptedJob()); + + sleep(1); + + $this->assertSame(1, Queue::size()); + $this->assertNotNull($job = Queue::pop()); + $this->assertSame(1, $job->attempts()); + $this->assertInstanceOf(RabbitMQJob::class, $job); + $this->assertSame(TestEncryptedJob::class, $job->resolveName()); + $this->assertNotNull($job->getJobId()); + + $payload = $job->payload(); + + $this->assertSame(TestEncryptedJob::class, $payload['displayName']); + $this->assertSame('Illuminate\Queue\CallQueuedHandler@call', $payload['job']); + $this->assertNull($payload['maxTries']); + $this->assertNull($payload['backoff']); + $this->assertNull($payload['timeout']); + $this->assertNull($payload['retryUntil']); + $this->assertSame($job->getJobId(), $payload['id']); + + $job->delete(); + $this->assertSame(0, Queue::size()); + } + + public function testPushEncryptedAfterCommit(): void + { + $transaction = new DatabaseTransactionsManager; + + $this->app->singleton('db.transactions', function ($app) use ($transaction) { + $transaction->begin('FakeDBConnection', 1); + + return $transaction; + }); + + TestEncryptedJob::dispatch()->afterCommit(); + + sleep(1); + $this->assertSame(0, Queue::size()); + $this->assertNull(Queue::pop()); + + $transaction->commit('FakeDBConnection', 1, 0); + + sleep(1); + + $this->assertSame(1, Queue::size()); + $this->assertNotNull($job = Queue::pop()); + + $job->delete(); + $this->assertSame(0, Queue::size()); + } + + public function testEncryptedLater(): void + { + Queue::later(3, new TestEncryptedJob()); + + sleep(1); + + $this->assertSame(0, Queue::size()); + $this->assertNull(Queue::pop()); + + sleep(3); + + $this->assertSame(1, Queue::size()); + $this->assertNotNull($job = Queue::pop()); + + $this->assertInstanceOf(RabbitMQJob::class, $job); + + $body = json_decode($job->getRawBody(), true); + + $this->assertSame(TestEncryptedJob::class, $body['displayName']); + $this->assertSame('Illuminate\Queue\CallQueuedHandler@call', $body['job']); + $this->assertSame(TestEncryptedJob::class, $body['data']['commandName']); + $this->assertNotNull($job->getJobId()); + + $job->delete(); + $this->assertSame(0, Queue::size()); + } + + public function testEncryptedBulk(): void + { + $count = 100; + $jobs = []; + + for ($i = 0; $i < $count; $i++) { + $jobs[$i] = new TestEncryptedJob($i); + } + + Queue::bulk($jobs); + + sleep(1); + + $this->assertSame($count, Queue::size()); + } + public function testReleaseRaw(): void { Queue::pushRaw($payload = Str::random()); diff --git a/tests/Mocks/TestEncryptedJob.php b/tests/Mocks/TestEncryptedJob.php new file mode 100644 index 00000000..1c0e1762 --- /dev/null +++ b/tests/Mocks/TestEncryptedJob.php @@ -0,0 +1,25 @@ +i = $i; + } + + public function handle(): void + { + // + } +} From 813086aa9bb6e56fef09219e43eba481f9f3f66e Mon Sep 17 00:00:00 2001 From: Fabien Villepinte Date: Mon, 8 Jul 2024 09:13:26 +0200 Subject: [PATCH 142/150] Document the exceptions thrown by publishBasic() --- src/Queue/RabbitMQQueue.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Queue/RabbitMQQueue.php b/src/Queue/RabbitMQQueue.php index ce63494d..957620ef 100644 --- a/src/Queue/RabbitMQQueue.php +++ b/src/Queue/RabbitMQQueue.php @@ -15,6 +15,7 @@ use PhpAmqpLib\Channel\AMQPChannel; use PhpAmqpLib\Connection\AbstractConnection; use PhpAmqpLib\Exception\AMQPChannelClosedException; +use PhpAmqpLib\Exception\AMQPConnectionBlockedException; use PhpAmqpLib\Exception\AMQPConnectionClosedException; use PhpAmqpLib\Exception\AMQPProtocolChannelException; use PhpAmqpLib\Exception\AMQPRuntimeException; @@ -739,6 +740,11 @@ protected function getConfig(): QueueConfig return $this->config; } + /** + * @throws AMQPChannelClosedException + * @throws AMQPConnectionClosedException + * @throws AMQPConnectionBlockedException + */ protected function publishBasic($msg, $exchange = '', $destination = '', $mandatory = false, $immediate = false, $ticket = null): void { $this->getChannel()->basic_publish($msg, $exchange, $destination, $mandatory, $immediate, $ticket); From aaad79f2c7dd0a918de8b43dfe6ee2f117d6da94 Mon Sep 17 00:00:00 2001 From: VojtaB Date: Thu, 12 Dec 2024 19:47:42 +0100 Subject: [PATCH 143/150] load timeouts from laravel config --- README.md | 27 ++++++++++++++++++++++++++ src/Queue/Connection/ConfigFactory.php | 24 +++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/README.md b/README.md index adb7b2e9..30a10df9 100644 --- a/README.md +++ b/README.md @@ -529,6 +529,33 @@ Available protocols : `tcp`, `ssl`, `tls` ], ``` +### Network Timeouts + +For network timeouts configuration you can use option parameters. +All float values are in seconds and zero value can mean infinite timeout. +Example contains default values. + +```php +'connections' => [ + // ... + + 'rabbitmq' => [ + // ... + + 'options' => [ + // ... + + 'connection_timeout' => 3.0, + 'read_timeout' => 3.0, + 'write_timeout' => 3.0, + 'channel_rpc_timeout' => 0.0, + ], + ], + + // ... +], +``` + ### Octane support Starting with 13.3.0, this package supports [Laravel Octane](https://laravel.com/docs/octane) out of the box. diff --git a/src/Queue/Connection/ConfigFactory.php b/src/Queue/Connection/ConfigFactory.php index 7783b9cd..8e013efd 100644 --- a/src/Queue/Connection/ConfigFactory.php +++ b/src/Queue/Connection/ConfigFactory.php @@ -38,6 +38,7 @@ public static function make(array $config = []): AMQPConnectionConfig self::getHostFromConfig($connectionConfig, $config); self::getHeartbeatFromConfig($connectionConfig, $config); self::getNetworkProtocolFromConfig($connectionConfig, $config); + self::getTimeoutsFromConfig($connectionConfig, $config); }); } @@ -99,4 +100,27 @@ protected static function getNetworkProtocolFromConfig(AMQPConnectionConfig $con $connectionConfig->setNetworkProtocol($networkProtocol); } } + + protected static function getTimeoutsFromConfig(AMQPConnectionConfig $connectionConfig, array $config): void + { + $connectionTimeout = Arr::get($config, self::CONFIG_OPTIONS.'.connection_timeout'); + if (is_numeric($connectionTimeout) && floatval($connectionTimeout) >= 0) { + $connectionConfig->setConnectionTimeout((float) $connectionTimeout); + } + + $readTimeout = Arr::get($config, self::CONFIG_OPTIONS.'.read_timeout'); + if (is_numeric($readTimeout) && floatval($readTimeout) >= 0) { + $connectionConfig->setReadTimeout((float) $readTimeout); + } + + $writeTimeout = Arr::get($config, self::CONFIG_OPTIONS.'.write_timeout'); + if (is_numeric($writeTimeout) && floatval($writeTimeout) >= 0) { + $connectionConfig->setWriteTimeout((float) $writeTimeout); + } + + $chanelRpcTimeout = Arr::get($config, self::CONFIG_OPTIONS.'.channel_rpc_timeout'); + if (is_numeric($chanelRpcTimeout) && floatval($chanelRpcTimeout) >= 0) { + $connectionConfig->setChannelRPCTimeout((float) $chanelRpcTimeout); + } + } } From c00a8cce370a1525cacfff2b7c5e11d666943e5a Mon Sep 17 00:00:00 2001 From: Sergey Tarasenko Date: Thu, 23 Jan 2025 00:19:27 +0300 Subject: [PATCH 144/150] pint fixes --- pint.json | 4 ++-- src/Horizon/RabbitMQQueue.php | 2 +- src/Queue/Connection/ConfigFactory.php | 2 +- src/Queue/QueueConfigFactory.php | 2 +- src/Queue/RabbitMQQueue.php | 14 +++++++------- tests/Feature/QueueTest.php | 6 +++--- tests/Feature/SslQueueTest.php | 2 +- tests/Feature/TestCase.php | 20 ++++++++++---------- tests/Functional/RabbitMQQueueTest.php | 2 +- tests/TestCase.php | 2 +- 10 files changed, 28 insertions(+), 28 deletions(-) diff --git a/pint.json b/pint.json index 751c2203..029010c0 100644 --- a/pint.json +++ b/pint.json @@ -1,8 +1,8 @@ { "preset": "laravel", "rules": { - "nullable_type_declaration_for_default_null_value": { - "use_nullable_type_declaration": false + "php_unit_method_casing": { + "case": "camel_case" } } } diff --git a/src/Horizon/RabbitMQQueue.php b/src/Horizon/RabbitMQQueue.php index 894cc24b..e2ca400d 100644 --- a/src/Horizon/RabbitMQQueue.php +++ b/src/Horizon/RabbitMQQueue.php @@ -26,7 +26,7 @@ class RabbitMQQueue extends BaseRabbitMQQueue * * @throws AMQPProtocolChannelException */ - public function readyNow(string $queue = null): int + public function readyNow(?string $queue = null): int { return $this->size($queue); } diff --git a/src/Queue/Connection/ConfigFactory.php b/src/Queue/Connection/ConfigFactory.php index 7783b9cd..f3ecd409 100644 --- a/src/Queue/Connection/ConfigFactory.php +++ b/src/Queue/Connection/ConfigFactory.php @@ -16,7 +16,7 @@ class ConfigFactory */ public static function make(array $config = []): AMQPConnectionConfig { - return tap(new AMQPConnectionConfig(), function (AMQPConnectionConfig $connectionConfig) use ($config) { + return tap(new AMQPConnectionConfig, function (AMQPConnectionConfig $connectionConfig) use ($config) { // Set the connection to a Lazy by default $connectionConfig->setIsLazy(! in_array( Arr::get($config, 'lazy') ?? true, diff --git a/src/Queue/QueueConfigFactory.php b/src/Queue/QueueConfigFactory.php index 87fc2fac..6f2befc5 100644 --- a/src/Queue/QueueConfigFactory.php +++ b/src/Queue/QueueConfigFactory.php @@ -13,7 +13,7 @@ class QueueConfigFactory */ public static function make(array $config = []): QueueConfig { - return tap(new QueueConfig(), function (QueueConfig $queueConfig) use ($config) { + return tap(new QueueConfig, function (QueueConfig $queueConfig) use ($config) { if (! empty($queue = Arr::get($config, 'queue'))) { $queueConfig->setQueue($queue); } diff --git a/src/Queue/RabbitMQQueue.php b/src/Queue/RabbitMQQueue.php index 957620ef..fadedce5 100644 --- a/src/Queue/RabbitMQQueue.php +++ b/src/Queue/RabbitMQQueue.php @@ -204,7 +204,7 @@ protected function publishBatch($jobs, $data = '', $queue = null): void /** * @throws AMQPProtocolChannelException */ - public function bulkRaw(string $payload, string $queue = null, array $options = []): int|string|null + public function bulkRaw(string $payload, ?string $queue = null, array $options = []): int|string|null { [$destination, $exchange, $exchangeType, $attempts] = $this->publishProperties($queue, $options); @@ -397,7 +397,7 @@ public function deleteExchange(string $name, bool $unused = false): void * * @throws AMQPProtocolChannelException */ - public function isQueueExists(string $name = null): bool + public function isQueueExists(?string $name = null): bool { $queueName = $this->getQueue($name); @@ -484,7 +484,7 @@ public function bindQueue(string $queue, string $exchange, string $routingKey = /** * Purge the queue of messages. */ - public function purge(string $queue = null): void + public function purge(?string $queue = null): void { // create a temporary channel, so the main channel will not be closed on exception $channel = $this->createChannel(); @@ -637,7 +637,7 @@ protected function getDelayQueueArguments(string $destination, int $ttl): array /** * Get the exchange name, or empty string; as default value. */ - protected function getExchange(string $exchange = null): string + protected function getExchange(?string $exchange = null): string { return $exchange ?? $this->getConfig()->getExchange(); } @@ -654,7 +654,7 @@ protected function getRoutingKey(string $destination): string /** * Get the exchangeType, or AMQPExchangeType::DIRECT as default. */ - protected function getExchangeType(string $type = null): string + protected function getExchangeType(?string $type = null): string { $constant = AMQPExchangeType::class.'::'.Str::upper($type ?: $this->getConfig()->getExchangeType()); @@ -664,7 +664,7 @@ protected function getExchangeType(string $type = null): string /** * Get the exchange for failed messages. */ - protected function getFailedExchange(string $exchange = null): string + protected function getFailedExchange(?string $exchange = null): string { return $exchange ?? $this->getConfig()->getFailedExchange(); } @@ -699,7 +699,7 @@ protected function isQueueDeclared(string $name): bool * * @throws AMQPProtocolChannelException */ - protected function declareDestination(string $destination, string $exchange = null, string $exchangeType = AMQPExchangeType::DIRECT): void + protected function declareDestination(string $destination, ?string $exchange = null, string $exchangeType = AMQPExchangeType::DIRECT): void { // When an exchange is provided and no exchange is present in RabbitMQ, create an exchange. if ($exchange && ! $this->isExchangeExists($exchange)) { diff --git a/tests/Feature/QueueTest.php b/tests/Feature/QueueTest.php index 5ecfb978..ee324c9a 100644 --- a/tests/Feature/QueueTest.php +++ b/tests/Feature/QueueTest.php @@ -10,7 +10,7 @@ class QueueTest extends TestCase { - public function setUp(): void + protected function setUp(): void { parent::setUp(); @@ -29,7 +29,7 @@ public function testWithoutReconnect(): void { $queue = $this->connection('rabbitmq'); - $queue->push(new TestJob()); + $queue->push(new TestJob); sleep(1); $this->assertSame(1, $queue->size()); @@ -38,6 +38,6 @@ public function testWithoutReconnect(): void $this->assertFalse($queue->getConnection()->isConnected()); $this->expectException(AMQPChannelClosedException::class); - $queue->push(new TestJob()); + $queue->push(new TestJob); } } diff --git a/tests/Feature/SslQueueTest.php b/tests/Feature/SslQueueTest.php index e9c460ea..02181c96 100644 --- a/tests/Feature/SslQueueTest.php +++ b/tests/Feature/SslQueueTest.php @@ -6,7 +6,7 @@ class SslQueueTest extends TestCase { - public function setUp(): void + protected function setUp(): void { $this->markTestSkipped(); } diff --git a/tests/Feature/TestCase.php b/tests/Feature/TestCase.php index 16fd5faa..5afda85d 100644 --- a/tests/Feature/TestCase.php +++ b/tests/Feature/TestCase.php @@ -17,7 +17,7 @@ abstract class TestCase extends BaseTestCase /** * @throws AMQPProtocolChannelException */ - public function setUp(): void + protected function setUp(): void { parent::setUp(); @@ -70,7 +70,7 @@ public function testPushRaw(): void public function testPush(): void { - Queue::push(new TestJob()); + Queue::push(new TestJob); sleep(1); @@ -154,7 +154,7 @@ public function testLaterRaw(): void public function testLater(): void { - Queue::later(3, new TestJob()); + Queue::later(3, new TestJob); sleep(1); @@ -197,7 +197,7 @@ public function testBulk(): void public function testPushEncrypted(): void { - Queue::push(new TestEncryptedJob()); + Queue::push(new TestEncryptedJob); sleep(1); @@ -251,7 +251,7 @@ public function testPushEncryptedAfterCommit(): void public function testEncryptedLater(): void { - Queue::later(3, new TestEncryptedJob()); + Queue::later(3, new TestEncryptedJob); sleep(1); @@ -320,7 +320,7 @@ public function testReleaseRaw(): void public function testRelease(): void { - Queue::push(new TestJob()); + Queue::push(new TestJob); sleep(1); @@ -377,7 +377,7 @@ public function testReleaseWithDelayRaw(): void public function testReleaseInThePast(): void { - Queue::push(new TestJob()); + Queue::push(new TestJob); $job = Queue::pop(); $job->release(-3); @@ -392,7 +392,7 @@ public function testReleaseInThePast(): void public function testReleaseAndReleaseWithDelayAttempts(): void { - Queue::push(new TestJob()); + Queue::push(new TestJob); sleep(1); @@ -419,7 +419,7 @@ public function testReleaseAndReleaseWithDelayAttempts(): void public function testDelete(): void { - Queue::push(new TestJob()); + Queue::push(new TestJob); $job = Queue::pop(); @@ -433,7 +433,7 @@ public function testDelete(): void public function testFailed(): void { - Queue::push(new TestJob()); + Queue::push(new TestJob); $job = Queue::pop(); diff --git a/tests/Functional/RabbitMQQueueTest.php b/tests/Functional/RabbitMQQueueTest.php index 7a106a08..1c5d94fb 100644 --- a/tests/Functional/RabbitMQQueueTest.php +++ b/tests/Functional/RabbitMQQueueTest.php @@ -87,7 +87,7 @@ public function testConfigExchangeType(): void $queue = $this->connection('rabbitmq-with-options-null'); $this->assertSame(AMQPExchangeType::DIRECT, $this->callMethod($queue, 'getExchangeType')); - //testing an unkown type with a default + // testing an unkown type with a default $this->callProperty($queue, 'config')->setExchangeType('unknown'); $this->assertSame(AMQPExchangeType::DIRECT, $this->callMethod($queue, 'getExchangeType')); } diff --git a/tests/TestCase.php b/tests/TestCase.php index 7d50fa67..f1ffb8d4 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -50,7 +50,7 @@ protected function getEnvironmentSetUp($app): void ]); } - protected function connection(string $name = null): RabbitMQQueue + protected function connection(?string $name = null): RabbitMQQueue { return Queue::connection($name); } From 4765c204d3c86aef9d6e1eda75a413c38efdad36 Mon Sep 17 00:00:00 2001 From: Samuel Fontebasso Date: Sun, 20 Apr 2025 01:45:50 -0300 Subject: [PATCH 145/150] style: fix formatting issues to pass lint/tests --- src/Queue/Connection/ConfigFactory.php | 2 +- src/Queue/QueueConfigFactory.php | 2 +- tests/Feature/ConnectorTest.php | 8 ++-- tests/Feature/QueueTest.php | 10 ++--- tests/Feature/SslQueueTest.php | 4 +- tests/Feature/TestCase.php | 58 +++++++++++++------------- tests/Functional/RabbitMQQueueTest.php | 30 ++++++------- tests/Functional/TestCase.php | 4 +- 8 files changed, 59 insertions(+), 59 deletions(-) diff --git a/src/Queue/Connection/ConfigFactory.php b/src/Queue/Connection/ConfigFactory.php index 7783b9cd..f3ecd409 100644 --- a/src/Queue/Connection/ConfigFactory.php +++ b/src/Queue/Connection/ConfigFactory.php @@ -16,7 +16,7 @@ class ConfigFactory */ public static function make(array $config = []): AMQPConnectionConfig { - return tap(new AMQPConnectionConfig(), function (AMQPConnectionConfig $connectionConfig) use ($config) { + return tap(new AMQPConnectionConfig, function (AMQPConnectionConfig $connectionConfig) use ($config) { // Set the connection to a Lazy by default $connectionConfig->setIsLazy(! in_array( Arr::get($config, 'lazy') ?? true, diff --git a/src/Queue/QueueConfigFactory.php b/src/Queue/QueueConfigFactory.php index 87fc2fac..6f2befc5 100644 --- a/src/Queue/QueueConfigFactory.php +++ b/src/Queue/QueueConfigFactory.php @@ -13,7 +13,7 @@ class QueueConfigFactory */ public static function make(array $config = []): QueueConfig { - return tap(new QueueConfig(), function (QueueConfig $queueConfig) use ($config) { + return tap(new QueueConfig, function (QueueConfig $queueConfig) use ($config) { if (! empty($queue = Arr::get($config, 'queue'))) { $queueConfig->setQueue($queue); } diff --git a/tests/Feature/ConnectorTest.php b/tests/Feature/ConnectorTest.php index 91660ad2..f4e330c3 100644 --- a/tests/Feature/ConnectorTest.php +++ b/tests/Feature/ConnectorTest.php @@ -12,7 +12,7 @@ class ConnectorTest extends \VladimirYuldashev\LaravelQueueRabbitMQ\Tests\TestCase { - public function testLazyConnection(): void + public function test_lazy_connection(): void { $this->app['config']->set('queue.connections.rabbitmq', [ 'driver' => 'rabbitmq', @@ -55,7 +55,7 @@ public function testLazyConnection(): void $this->assertTrue($connection->getConnection()->isConnected()); } - public function testLazyStreamConnection(): void + public function test_lazy_stream_connection(): void { $this->app['config']->set('queue.connections.rabbitmq', [ 'driver' => 'rabbitmq', @@ -98,7 +98,7 @@ public function testLazyStreamConnection(): void $this->assertTrue($connection->getConnection()->isConnected()); } - public function testSslConnection(): void + public function test_ssl_connection(): void { $this->markTestSkipped(); @@ -142,7 +142,7 @@ public function testSslConnection(): void } // Test to validate ssl connection params - public function testNoVerificationSslConnection(): void + public function test_no_verification_ssl_connection(): void { $this->app['config']->set('queue.connections.rabbitmq', [ 'driver' => 'rabbitmq', diff --git a/tests/Feature/QueueTest.php b/tests/Feature/QueueTest.php index 5ecfb978..609a48d8 100644 --- a/tests/Feature/QueueTest.php +++ b/tests/Feature/QueueTest.php @@ -10,7 +10,7 @@ class QueueTest extends TestCase { - public function setUp(): void + protected function setUp(): void { parent::setUp(); @@ -20,16 +20,16 @@ public function setUp(): void ]); } - public function testConnection(): void + public function test_connection(): void { $this->assertInstanceOf(AMQPStreamConnection::class, $this->connection()->getChannel()->getConnection()); } - public function testWithoutReconnect(): void + public function test_without_reconnect(): void { $queue = $this->connection('rabbitmq'); - $queue->push(new TestJob()); + $queue->push(new TestJob); sleep(1); $this->assertSame(1, $queue->size()); @@ -38,6 +38,6 @@ public function testWithoutReconnect(): void $this->assertFalse($queue->getConnection()->isConnected()); $this->expectException(AMQPChannelClosedException::class); - $queue->push(new TestJob()); + $queue->push(new TestJob); } } diff --git a/tests/Feature/SslQueueTest.php b/tests/Feature/SslQueueTest.php index e9c460ea..53cf5d38 100644 --- a/tests/Feature/SslQueueTest.php +++ b/tests/Feature/SslQueueTest.php @@ -6,7 +6,7 @@ class SslQueueTest extends TestCase { - public function setUp(): void + protected function setUp(): void { $this->markTestSkipped(); } @@ -43,7 +43,7 @@ protected function getEnvironmentSetUp($app): void ]); } - public function testConnection(): void + public function test_connection(): void { $this->assertInstanceOf(AMQPSSLConnection::class, $this->connection()->getChannel()->getConnection()); } diff --git a/tests/Feature/TestCase.php b/tests/Feature/TestCase.php index 16fd5faa..7d0fab9a 100644 --- a/tests/Feature/TestCase.php +++ b/tests/Feature/TestCase.php @@ -17,7 +17,7 @@ abstract class TestCase extends BaseTestCase /** * @throws AMQPProtocolChannelException */ - public function setUp(): void + protected function setUp(): void { parent::setUp(); @@ -40,17 +40,17 @@ protected function tearDown(): void parent::tearDown(); } - public function testSizeDoesNotThrowExceptionOnUnknownQueue(): void + public function test_size_does_not_throw_exception_on_unknown_queue(): void { $this->assertEmpty(0, Queue::size(Str::random())); } - public function testPopNothing(): void + public function test_pop_nothing(): void { $this->assertNull(Queue::pop('foo')); } - public function testPushRaw(): void + public function test_push_raw(): void { Queue::pushRaw($payload = Str::random()); @@ -68,9 +68,9 @@ public function testPushRaw(): void $this->assertSame(0, Queue::size()); } - public function testPush(): void + public function test_push(): void { - Queue::push(new TestJob()); + Queue::push(new TestJob); sleep(1); @@ -95,7 +95,7 @@ public function testPush(): void $this->assertSame(0, Queue::size()); } - public function testPushAfterCommit(): void + public function test_push_after_commit(): void { $transaction = new DatabaseTransactionsManager; @@ -122,7 +122,7 @@ public function testPushAfterCommit(): void $this->assertSame(0, Queue::size()); } - public function testLaterRaw(): void + public function test_later_raw(): void { $payload = Str::random(); $data = [Str::random() => Str::random()]; @@ -152,9 +152,9 @@ public function testLaterRaw(): void $this->assertSame(0, Queue::size()); } - public function testLater(): void + public function test_later(): void { - Queue::later(3, new TestJob()); + Queue::later(3, new TestJob); sleep(1); @@ -179,7 +179,7 @@ public function testLater(): void $this->assertSame(0, Queue::size()); } - public function testBulk(): void + public function test_bulk(): void { $count = 100; $jobs = []; @@ -195,9 +195,9 @@ public function testBulk(): void $this->assertSame($count, Queue::size()); } - public function testPushEncrypted(): void + public function test_push_encrypted(): void { - Queue::push(new TestEncryptedJob()); + Queue::push(new TestEncryptedJob); sleep(1); @@ -222,7 +222,7 @@ public function testPushEncrypted(): void $this->assertSame(0, Queue::size()); } - public function testPushEncryptedAfterCommit(): void + public function test_push_encrypted_after_commit(): void { $transaction = new DatabaseTransactionsManager; @@ -249,9 +249,9 @@ public function testPushEncryptedAfterCommit(): void $this->assertSame(0, Queue::size()); } - public function testEncryptedLater(): void + public function test_encrypted_later(): void { - Queue::later(3, new TestEncryptedJob()); + Queue::later(3, new TestEncryptedJob); sleep(1); @@ -276,7 +276,7 @@ public function testEncryptedLater(): void $this->assertSame(0, Queue::size()); } - public function testEncryptedBulk(): void + public function test_encrypted_bulk(): void { $count = 100; $jobs = []; @@ -292,7 +292,7 @@ public function testEncryptedBulk(): void $this->assertSame($count, Queue::size()); } - public function testReleaseRaw(): void + public function test_release_raw(): void { Queue::pushRaw($payload = Str::random()); @@ -318,9 +318,9 @@ public function testReleaseRaw(): void $this->assertSame(0, Queue::size()); } - public function testRelease(): void + public function test_release(): void { - Queue::push(new TestJob()); + Queue::push(new TestJob); sleep(1); @@ -344,7 +344,7 @@ public function testRelease(): void $this->assertSame(0, Queue::size()); } - public function testReleaseWithDelayRaw(): void + public function test_release_with_delay_raw(): void { Queue::pushRaw($payload = Str::random()); @@ -375,9 +375,9 @@ public function testReleaseWithDelayRaw(): void $this->assertSame(0, Queue::size()); } - public function testReleaseInThePast(): void + public function test_release_in_the_past(): void { - Queue::push(new TestJob()); + Queue::push(new TestJob); $job = Queue::pop(); $job->release(-3); @@ -390,9 +390,9 @@ public function testReleaseInThePast(): void $this->assertSame(0, Queue::size()); } - public function testReleaseAndReleaseWithDelayAttempts(): void + public function test_release_and_release_with_delay_attempts(): void { - Queue::push(new TestJob()); + Queue::push(new TestJob); sleep(1); @@ -417,9 +417,9 @@ public function testReleaseAndReleaseWithDelayAttempts(): void $this->assertSame(0, Queue::size()); } - public function testDelete(): void + public function test_delete(): void { - Queue::push(new TestJob()); + Queue::push(new TestJob); $job = Queue::pop(); @@ -431,9 +431,9 @@ public function testDelete(): void $this->assertNull(Queue::pop()); } - public function testFailed(): void + public function test_failed(): void { - Queue::push(new TestJob()); + Queue::push(new TestJob); $job = Queue::pop(); diff --git a/tests/Functional/RabbitMQQueueTest.php b/tests/Functional/RabbitMQQueueTest.php index 7a106a08..21a2e1d4 100644 --- a/tests/Functional/RabbitMQQueueTest.php +++ b/tests/Functional/RabbitMQQueueTest.php @@ -9,7 +9,7 @@ class RabbitMQQueueTest extends BaseTestCase { - public function testConnection(): void + public function test_connection(): void { $queue = $this->connection(); $this->assertInstanceOf(RabbitMQQueue::class, $queue); @@ -21,7 +21,7 @@ public function testConnection(): void $this->assertInstanceOf(RabbitMQQueue::class, $queue); } - public function testConfigRerouteFailed(): void + public function test_config_reroute_failed(): void { $queue = $this->connection(); $this->assertFalse($this->callProperty($queue, 'config')->isRerouteFailed()); @@ -36,7 +36,7 @@ public function testConfigRerouteFailed(): void $this->assertFalse($this->callProperty($queue, 'config')->isRerouteFailed()); } - public function testConfigPrioritizeDelayed(): void + public function test_config_prioritize_delayed(): void { $queue = $this->connection(); $this->assertFalse($this->callProperty($queue, 'config')->isPrioritizeDelayed()); @@ -51,7 +51,7 @@ public function testConfigPrioritizeDelayed(): void $this->assertFalse($this->callProperty($queue, 'config')->isPrioritizeDelayed()); } - public function testQueueMaxPriority(): void + public function test_queue_max_priority(): void { $queue = $this->connection(); $this->assertIsInt($this->callProperty($queue, 'config')->getQueueMaxPriority()); @@ -70,7 +70,7 @@ public function testQueueMaxPriority(): void $this->assertSame(2, $this->callProperty($queue, 'config')->getQueueMaxPriority()); } - public function testConfigExchangeType(): void + public function test_config_exchange_type(): void { $queue = $this->connection(); $this->assertSame(AMQPExchangeType::DIRECT, $this->callMethod($queue, 'getExchangeType')); @@ -87,12 +87,12 @@ public function testConfigExchangeType(): void $queue = $this->connection('rabbitmq-with-options-null'); $this->assertSame(AMQPExchangeType::DIRECT, $this->callMethod($queue, 'getExchangeType')); - //testing an unkown type with a default + // testing an unkown type with a default $this->callProperty($queue, 'config')->setExchangeType('unknown'); $this->assertSame(AMQPExchangeType::DIRECT, $this->callMethod($queue, 'getExchangeType')); } - public function testExchange(): void + public function test_exchange(): void { $queue = $this->connection(); $this->assertSame('test', $this->callMethod($queue, 'getExchange', ['test'])); @@ -119,7 +119,7 @@ public function testExchange(): void $this->assertSame('', $this->callMethod($queue, 'getExchange', [''])); } - public function testFailedExchange(): void + public function test_failed_exchange(): void { $queue = $this->connection(); $this->assertSame('test', $this->callMethod($queue, 'getFailedExchange', ['test'])); @@ -146,7 +146,7 @@ public function testFailedExchange(): void $this->assertSame('', $this->callMethod($queue, 'getFailedExchange', [''])); } - public function testRoutingKey(): void + public function test_routing_key(): void { $queue = $this->connection(); $this->assertSame('test', $this->callMethod($queue, 'getRoutingKey', ['test'])); @@ -165,7 +165,7 @@ public function testRoutingKey(): void $this->assertSame('an.alternate.routing-key', $this->callMethod($queue, 'getRoutingKey', ['test'])); } - public function testFailedRoutingKey(): void + public function test_failed_routing_key(): void { $queue = $this->connection(); $this->assertSame('test.failed', $this->callMethod($queue, 'getFailedRoutingKey', ['test'])); @@ -184,7 +184,7 @@ public function testFailedRoutingKey(): void $this->assertSame('an.alternate.routing-key', $this->callMethod($queue, 'getFailedRoutingKey', ['test'])); } - public function testConfigQuorum(): void + public function test_config_quorum(): void { $queue = $this->connection(); $this->assertFalse($this->callProperty($queue, 'config')->isQuorum()); @@ -202,7 +202,7 @@ public function testConfigQuorum(): void $this->assertTrue($this->callProperty($queue, 'config')->isQuorum()); } - public function testDeclareDeleteExchange(): void + public function test_declare_delete_exchange(): void { $queue = $this->connection(); @@ -217,7 +217,7 @@ public function testDeclareDeleteExchange(): void $this->assertFalse($queue->isExchangeExists($name)); } - public function testDeclareDeleteQueue(): void + public function test_declare_delete_queue(): void { $queue = $this->connection(); @@ -232,7 +232,7 @@ public function testDeclareDeleteQueue(): void $this->assertFalse($queue->isQueueExists($name)); } - public function testQueueArguments(): void + public function test_queue_arguments(): void { $name = Str::random(); @@ -272,7 +272,7 @@ public function testQueueArguments(): void $this->assertEquals(array_values($expected), array_values($actual)); } - public function testDelayQueueArguments(): void + public function test_delay_queue_arguments(): void { $name = Str::random(); $ttl = 12000; diff --git a/tests/Functional/TestCase.php b/tests/Functional/TestCase.php index 8b843561..b21aeaf8 100644 --- a/tests/Functional/TestCase.php +++ b/tests/Functional/TestCase.php @@ -236,7 +236,7 @@ protected function callProperty($object, string $property): mixed return $property->getValue($object); } - public function testConnectChannel(): void + public function test_connect_channel(): void { $queue = $this->connection(); $this->assertFalse($queue->getConnection()->isConnected()); @@ -248,7 +248,7 @@ public function testConnectChannel(): void $this->assertTrue($channel->is_open()); } - public function testReconnect(): void + public function test_reconnect(): void { $queue = $this->connection(); $this->assertFalse($queue->getConnection()->isConnected()); From 9c5fa17a0aa0d175d4849703553997b6edb72613 Mon Sep 17 00:00:00 2001 From: Samuel Fontebasso Date: Sun, 20 Apr 2025 02:01:38 -0300 Subject: [PATCH 146/150] fix: remove manual docker-compose v1 install to prevent CI failure on ubuntu-latest --- .github/workflows/tests.yml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index fccb0608..0da38f44 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -33,15 +33,8 @@ jobs: extensions: dom, curl, libxml, mbstring, zip coverage: none - - name: Set up Docker - run: | - sudo rm /usr/local/bin/docker-compose - curl -L https://github.com/docker/compose/releases/download/1.24.1/docker-compose-`uname -s`-`uname -m` > docker-compose - chmod +x docker-compose - sudo mv docker-compose /usr/local/bin - - name: Start Docker container - run: docker-compose up -d rabbitmq + run: docker compose up -d rabbitmq - name: Install dependencies run: composer update --with='laravel/framework:${{matrix.laravel}}' --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress From e69dd13ebfde40ae6993ee977e67ca22bd3e9609 Mon Sep 17 00:00:00 2001 From: Samuel Fontebasso Date: Mon, 21 Apr 2025 15:28:51 -0300 Subject: [PATCH 147/150] feat: add Laravel 12 support and fix test connection by disabling SSL verify_peer --- .github/workflows/tests.yml | 4 +++- composer.json | 6 +++--- tests/TestCase.php | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0da38f44..d0588c10 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -15,10 +15,12 @@ jobs: matrix: php: ['8.1', '8.2', '8.3'] stability: ['prefer-lowest', 'prefer-stable'] - laravel: ['^10.0', '^11.0'] + laravel: ['^10.0', '^11.0', '^12.0'] exclude: - php: '8.1' laravel: '^11.0' + - php: '8.1' + laravel: '^12.0' name: 'PHP ${{ matrix.php }} - Laravel: ${{matrix.laravel}} - ${{ matrix.stability }}' diff --git a/composer.json b/composer.json index 1a91d725..caf8a0fc 100644 --- a/composer.json +++ b/composer.json @@ -11,16 +11,16 @@ "require": { "php": "^8.0", "ext-json": "*", - "illuminate/queue": "^10.0|^11.0", + "illuminate/queue": "^10.0|^11.0|^12.0", "php-amqplib/php-amqplib": "^v3.6" }, "require-dev": { "phpunit/phpunit": "^10.0|^11.0", "mockery/mockery": "^1.0", "laravel/horizon": "^5.0", - "orchestra/testbench": "^7.0|^8.0|^9.0", + "orchestra/testbench": "^7.0|^8.0|^9.0|^10.0", "laravel/pint": "^1.2", - "laravel/framework": "^9.0|^10.0|^11.0" + "laravel/framework": "^9.0|^10.0|^11.0|^12.0" }, "autoload": { "psr-4": { diff --git a/tests/TestCase.php b/tests/TestCase.php index 7d50fa67..f3f0705d 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -40,7 +40,7 @@ protected function getEnvironmentSetUp($app): void 'cafile' => null, 'local_cert' => null, 'local_key' => null, - 'verify_peer' => true, + 'verify_peer' => false, 'passphrase' => null, ], ], From 6faa83ac6554a0b8340756c7ffee0f7b68741cd7 Mon Sep 17 00:00:00 2001 From: Samuel Fontebasso Date: Mon, 21 Apr 2025 17:02:52 -0300 Subject: [PATCH 148/150] feat: add --json flag to rabbitmq:consume and align option order with WorkCommand --- src/Console/ConsumeCommand.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Console/ConsumeCommand.php b/src/Console/ConsumeCommand.php index 50aab1d4..4072132a 100644 --- a/src/Console/ConsumeCommand.php +++ b/src/Console/ConsumeCommand.php @@ -21,9 +21,10 @@ class ConsumeCommand extends WorkCommand {--force : Force the worker to run even in maintenance mode} {--memory=128 : The memory limit in megabytes} {--sleep=3 : Number of seconds to sleep when no job is available} + {--rest=0 : Number of seconds to rest between jobs} {--timeout=60 : The number of seconds a child process can run} {--tries=1 : Number of times to attempt a job before logging it failed} - {--rest=0 : Number of seconds to rest between jobs} + {--json : Output the queue worker information as JSON} {--max-priority=} {--consumer-tag} From 4717111a1e3f7e70cc0e43e7752a5720fdd86207 Mon Sep 17 00:00:00 2001 From: Samuel Fontebasso Date: Wed, 30 Apr 2025 21:58:45 -0300 Subject: [PATCH 149/150] chore(ci): add PHP 8.4 to test matrix --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d0588c10..4aad6d20 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,7 +13,7 @@ jobs: strategy: fail-fast: true matrix: - php: ['8.1', '8.2', '8.3'] + php: ['8.1', '8.2', '8.3', '8.4'] stability: ['prefer-lowest', 'prefer-stable'] laravel: ['^10.0', '^11.0', '^12.0'] exclude: From e82de4ceef0ab3ddf5f4aaaa2816ea4c2dc49ef5 Mon Sep 17 00:00:00 2001 From: Samuel Fontebasso Date: Wed, 30 Apr 2025 22:24:44 -0300 Subject: [PATCH 150/150] style: rename PHPUnit test methods to camelCase --- pint.json | 2 +- tests/Feature/ConnectorTest.php | 8 +++--- tests/Feature/QueueTest.php | 4 +-- tests/Feature/SslQueueTest.php | 2 +- tests/Feature/TestCase.php | 38 +++++++++++++------------- tests/Functional/RabbitMQQueueTest.php | 28 +++++++++---------- tests/Functional/TestCase.php | 4 +-- 7 files changed, 43 insertions(+), 43 deletions(-) diff --git a/pint.json b/pint.json index 029010c0..05f4b41e 100644 --- a/pint.json +++ b/pint.json @@ -2,7 +2,7 @@ "preset": "laravel", "rules": { "php_unit_method_casing": { - "case": "camel_case" + "case": "camel_case" } } } diff --git a/tests/Feature/ConnectorTest.php b/tests/Feature/ConnectorTest.php index f4e330c3..91660ad2 100644 --- a/tests/Feature/ConnectorTest.php +++ b/tests/Feature/ConnectorTest.php @@ -12,7 +12,7 @@ class ConnectorTest extends \VladimirYuldashev\LaravelQueueRabbitMQ\Tests\TestCase { - public function test_lazy_connection(): void + public function testLazyConnection(): void { $this->app['config']->set('queue.connections.rabbitmq', [ 'driver' => 'rabbitmq', @@ -55,7 +55,7 @@ public function test_lazy_connection(): void $this->assertTrue($connection->getConnection()->isConnected()); } - public function test_lazy_stream_connection(): void + public function testLazyStreamConnection(): void { $this->app['config']->set('queue.connections.rabbitmq', [ 'driver' => 'rabbitmq', @@ -98,7 +98,7 @@ public function test_lazy_stream_connection(): void $this->assertTrue($connection->getConnection()->isConnected()); } - public function test_ssl_connection(): void + public function testSslConnection(): void { $this->markTestSkipped(); @@ -142,7 +142,7 @@ public function test_ssl_connection(): void } // Test to validate ssl connection params - public function test_no_verification_ssl_connection(): void + public function testNoVerificationSslConnection(): void { $this->app['config']->set('queue.connections.rabbitmq', [ 'driver' => 'rabbitmq', diff --git a/tests/Feature/QueueTest.php b/tests/Feature/QueueTest.php index 609a48d8..ee324c9a 100644 --- a/tests/Feature/QueueTest.php +++ b/tests/Feature/QueueTest.php @@ -20,12 +20,12 @@ protected function setUp(): void ]); } - public function test_connection(): void + public function testConnection(): void { $this->assertInstanceOf(AMQPStreamConnection::class, $this->connection()->getChannel()->getConnection()); } - public function test_without_reconnect(): void + public function testWithoutReconnect(): void { $queue = $this->connection('rabbitmq'); diff --git a/tests/Feature/SslQueueTest.php b/tests/Feature/SslQueueTest.php index 53cf5d38..02181c96 100644 --- a/tests/Feature/SslQueueTest.php +++ b/tests/Feature/SslQueueTest.php @@ -43,7 +43,7 @@ protected function getEnvironmentSetUp($app): void ]); } - public function test_connection(): void + public function testConnection(): void { $this->assertInstanceOf(AMQPSSLConnection::class, $this->connection()->getChannel()->getConnection()); } diff --git a/tests/Feature/TestCase.php b/tests/Feature/TestCase.php index 7d0fab9a..5afda85d 100644 --- a/tests/Feature/TestCase.php +++ b/tests/Feature/TestCase.php @@ -40,17 +40,17 @@ protected function tearDown(): void parent::tearDown(); } - public function test_size_does_not_throw_exception_on_unknown_queue(): void + public function testSizeDoesNotThrowExceptionOnUnknownQueue(): void { $this->assertEmpty(0, Queue::size(Str::random())); } - public function test_pop_nothing(): void + public function testPopNothing(): void { $this->assertNull(Queue::pop('foo')); } - public function test_push_raw(): void + public function testPushRaw(): void { Queue::pushRaw($payload = Str::random()); @@ -68,7 +68,7 @@ public function test_push_raw(): void $this->assertSame(0, Queue::size()); } - public function test_push(): void + public function testPush(): void { Queue::push(new TestJob); @@ -95,7 +95,7 @@ public function test_push(): void $this->assertSame(0, Queue::size()); } - public function test_push_after_commit(): void + public function testPushAfterCommit(): void { $transaction = new DatabaseTransactionsManager; @@ -122,7 +122,7 @@ public function test_push_after_commit(): void $this->assertSame(0, Queue::size()); } - public function test_later_raw(): void + public function testLaterRaw(): void { $payload = Str::random(); $data = [Str::random() => Str::random()]; @@ -152,7 +152,7 @@ public function test_later_raw(): void $this->assertSame(0, Queue::size()); } - public function test_later(): void + public function testLater(): void { Queue::later(3, new TestJob); @@ -179,7 +179,7 @@ public function test_later(): void $this->assertSame(0, Queue::size()); } - public function test_bulk(): void + public function testBulk(): void { $count = 100; $jobs = []; @@ -195,7 +195,7 @@ public function test_bulk(): void $this->assertSame($count, Queue::size()); } - public function test_push_encrypted(): void + public function testPushEncrypted(): void { Queue::push(new TestEncryptedJob); @@ -222,7 +222,7 @@ public function test_push_encrypted(): void $this->assertSame(0, Queue::size()); } - public function test_push_encrypted_after_commit(): void + public function testPushEncryptedAfterCommit(): void { $transaction = new DatabaseTransactionsManager; @@ -249,7 +249,7 @@ public function test_push_encrypted_after_commit(): void $this->assertSame(0, Queue::size()); } - public function test_encrypted_later(): void + public function testEncryptedLater(): void { Queue::later(3, new TestEncryptedJob); @@ -276,7 +276,7 @@ public function test_encrypted_later(): void $this->assertSame(0, Queue::size()); } - public function test_encrypted_bulk(): void + public function testEncryptedBulk(): void { $count = 100; $jobs = []; @@ -292,7 +292,7 @@ public function test_encrypted_bulk(): void $this->assertSame($count, Queue::size()); } - public function test_release_raw(): void + public function testReleaseRaw(): void { Queue::pushRaw($payload = Str::random()); @@ -318,7 +318,7 @@ public function test_release_raw(): void $this->assertSame(0, Queue::size()); } - public function test_release(): void + public function testRelease(): void { Queue::push(new TestJob); @@ -344,7 +344,7 @@ public function test_release(): void $this->assertSame(0, Queue::size()); } - public function test_release_with_delay_raw(): void + public function testReleaseWithDelayRaw(): void { Queue::pushRaw($payload = Str::random()); @@ -375,7 +375,7 @@ public function test_release_with_delay_raw(): void $this->assertSame(0, Queue::size()); } - public function test_release_in_the_past(): void + public function testReleaseInThePast(): void { Queue::push(new TestJob); @@ -390,7 +390,7 @@ public function test_release_in_the_past(): void $this->assertSame(0, Queue::size()); } - public function test_release_and_release_with_delay_attempts(): void + public function testReleaseAndReleaseWithDelayAttempts(): void { Queue::push(new TestJob); @@ -417,7 +417,7 @@ public function test_release_and_release_with_delay_attempts(): void $this->assertSame(0, Queue::size()); } - public function test_delete(): void + public function testDelete(): void { Queue::push(new TestJob); @@ -431,7 +431,7 @@ public function test_delete(): void $this->assertNull(Queue::pop()); } - public function test_failed(): void + public function testFailed(): void { Queue::push(new TestJob); diff --git a/tests/Functional/RabbitMQQueueTest.php b/tests/Functional/RabbitMQQueueTest.php index 21a2e1d4..1c5d94fb 100644 --- a/tests/Functional/RabbitMQQueueTest.php +++ b/tests/Functional/RabbitMQQueueTest.php @@ -9,7 +9,7 @@ class RabbitMQQueueTest extends BaseTestCase { - public function test_connection(): void + public function testConnection(): void { $queue = $this->connection(); $this->assertInstanceOf(RabbitMQQueue::class, $queue); @@ -21,7 +21,7 @@ public function test_connection(): void $this->assertInstanceOf(RabbitMQQueue::class, $queue); } - public function test_config_reroute_failed(): void + public function testConfigRerouteFailed(): void { $queue = $this->connection(); $this->assertFalse($this->callProperty($queue, 'config')->isRerouteFailed()); @@ -36,7 +36,7 @@ public function test_config_reroute_failed(): void $this->assertFalse($this->callProperty($queue, 'config')->isRerouteFailed()); } - public function test_config_prioritize_delayed(): void + public function testConfigPrioritizeDelayed(): void { $queue = $this->connection(); $this->assertFalse($this->callProperty($queue, 'config')->isPrioritizeDelayed()); @@ -51,7 +51,7 @@ public function test_config_prioritize_delayed(): void $this->assertFalse($this->callProperty($queue, 'config')->isPrioritizeDelayed()); } - public function test_queue_max_priority(): void + public function testQueueMaxPriority(): void { $queue = $this->connection(); $this->assertIsInt($this->callProperty($queue, 'config')->getQueueMaxPriority()); @@ -70,7 +70,7 @@ public function test_queue_max_priority(): void $this->assertSame(2, $this->callProperty($queue, 'config')->getQueueMaxPriority()); } - public function test_config_exchange_type(): void + public function testConfigExchangeType(): void { $queue = $this->connection(); $this->assertSame(AMQPExchangeType::DIRECT, $this->callMethod($queue, 'getExchangeType')); @@ -92,7 +92,7 @@ public function test_config_exchange_type(): void $this->assertSame(AMQPExchangeType::DIRECT, $this->callMethod($queue, 'getExchangeType')); } - public function test_exchange(): void + public function testExchange(): void { $queue = $this->connection(); $this->assertSame('test', $this->callMethod($queue, 'getExchange', ['test'])); @@ -119,7 +119,7 @@ public function test_exchange(): void $this->assertSame('', $this->callMethod($queue, 'getExchange', [''])); } - public function test_failed_exchange(): void + public function testFailedExchange(): void { $queue = $this->connection(); $this->assertSame('test', $this->callMethod($queue, 'getFailedExchange', ['test'])); @@ -146,7 +146,7 @@ public function test_failed_exchange(): void $this->assertSame('', $this->callMethod($queue, 'getFailedExchange', [''])); } - public function test_routing_key(): void + public function testRoutingKey(): void { $queue = $this->connection(); $this->assertSame('test', $this->callMethod($queue, 'getRoutingKey', ['test'])); @@ -165,7 +165,7 @@ public function test_routing_key(): void $this->assertSame('an.alternate.routing-key', $this->callMethod($queue, 'getRoutingKey', ['test'])); } - public function test_failed_routing_key(): void + public function testFailedRoutingKey(): void { $queue = $this->connection(); $this->assertSame('test.failed', $this->callMethod($queue, 'getFailedRoutingKey', ['test'])); @@ -184,7 +184,7 @@ public function test_failed_routing_key(): void $this->assertSame('an.alternate.routing-key', $this->callMethod($queue, 'getFailedRoutingKey', ['test'])); } - public function test_config_quorum(): void + public function testConfigQuorum(): void { $queue = $this->connection(); $this->assertFalse($this->callProperty($queue, 'config')->isQuorum()); @@ -202,7 +202,7 @@ public function test_config_quorum(): void $this->assertTrue($this->callProperty($queue, 'config')->isQuorum()); } - public function test_declare_delete_exchange(): void + public function testDeclareDeleteExchange(): void { $queue = $this->connection(); @@ -217,7 +217,7 @@ public function test_declare_delete_exchange(): void $this->assertFalse($queue->isExchangeExists($name)); } - public function test_declare_delete_queue(): void + public function testDeclareDeleteQueue(): void { $queue = $this->connection(); @@ -232,7 +232,7 @@ public function test_declare_delete_queue(): void $this->assertFalse($queue->isQueueExists($name)); } - public function test_queue_arguments(): void + public function testQueueArguments(): void { $name = Str::random(); @@ -272,7 +272,7 @@ public function test_queue_arguments(): void $this->assertEquals(array_values($expected), array_values($actual)); } - public function test_delay_queue_arguments(): void + public function testDelayQueueArguments(): void { $name = Str::random(); $ttl = 12000; diff --git a/tests/Functional/TestCase.php b/tests/Functional/TestCase.php index b21aeaf8..8b843561 100644 --- a/tests/Functional/TestCase.php +++ b/tests/Functional/TestCase.php @@ -236,7 +236,7 @@ protected function callProperty($object, string $property): mixed return $property->getValue($object); } - public function test_connect_channel(): void + public function testConnectChannel(): void { $queue = $this->connection(); $this->assertFalse($queue->getConnection()->isConnected()); @@ -248,7 +248,7 @@ public function test_connect_channel(): void $this->assertTrue($channel->is_open()); } - public function test_reconnect(): void + public function testReconnect(): void { $queue = $this->connection(); $this->assertFalse($queue->getConnection()->isConnected());