Skip to content

Commit d31c0aa

Browse files
abublihissi-anik
andauthored
Add support for laravel octane (#12)
* Add support for laravel octane, by keeping the resolved Producer and Consumer service container will keep the connection active for all requests coming to the same worker * readme update * reverted the consumer connection property * indentation fix * testcase added for producer reusability --------- Co-authored-by: Syed Sirajul Islam Anik <[email protected]>
1 parent 1f6ef40 commit d31c0aa

File tree

3 files changed

+54
-9
lines changed

3 files changed

+54
-9
lines changed

readme.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,21 @@ name.
8484
- `amqp.connections.*.consumer` holds the default properties of consumer when consuming.
8585
- `amqp.connections.*.qos` holds the default properties of QoS when consuming.
8686

87+
### Octane support
88+
89+
This package supports laravel octane by
90+
default. [To keep the AMQP connection alive](https://www.cloudamqp.com/blog/part4-rabbitmq-13-common-errors.html),
91+
you have to configure octane to `warm` the connection, by adding **'amqp'** to the warm array in octane configurations.
92+
93+
```php
94+
// config/octane.php
95+
// ...
96+
'warm' => [
97+
// ...
98+
'amqp', // <-- this line
99+
],
100+
```
101+
87102
## Usage
88103

89104
The followings work the same.
@@ -274,6 +289,7 @@ class MyTest extends TestCase
274289
- If a message exactly matches the `$message`.
275290
- If a message exactly matches the `get_class($message)`.
276291
- If a message is an implementation of `$message`.
292+
277293
### Note
278294

279295
Using `Anik\Laravel\Amqp\Facades\Amqp::consume()` after `Anik\Laravel\Amqp\Facades\Amqp::fake()` will throw exception.

src/Amqp.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ class Amqp implements AmqpPubSub
2020

2121
private $config;
2222

23+
private Producer $producer;
24+
2325
public function __construct(AbstractConnection $connection, array $config = [])
2426
{
2527
$this->connection = $connection;
@@ -28,7 +30,7 @@ public function __construct(AbstractConnection $connection, array $config = [])
2830

2931
public function getProducer(): Producer
3032
{
31-
return app()->make(Producer::class, ['connection' => $this->connection]);
33+
return $this->producer ??= app()->make(Producer::class, ['connection' => $this->connection]);
3234
}
3335

3436
public function getConsumer(array $options = []): Consumer

tests/AmqpTest.php

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ public static function consumerConfigTestDataProvider(): array
347347
/**
348348
* @dataProvider publishMessageTestDataProvider
349349
*
350-
* @param array $data
350+
* @param array $data
351351
*/
352352
public function testPublishFormatsMessagesToProducible(array $data)
353353
{
@@ -432,7 +432,7 @@ public function testPublishPassesExpectedRoutingKey()
432432
/**
433433
* @dataProvider publishOptionsDataProvider
434434
*
435-
* @param array $data
435+
* @param array $data
436436
*/
437437
public function testPublishPassesPublishOptionsIfAvailable(array $data)
438438
{
@@ -471,7 +471,7 @@ function ($options) use ($expectations) {
471471
/**
472472
* @dataProvider exchangeTestDataProvider
473473
*
474-
* @param array $data
474+
* @param array $data
475475
*/
476476
public function testPublishMessageProcessesExchange(array $data)
477477
{
@@ -511,6 +511,33 @@ function ($options) use ($expectation) {
511511
);
512512
}
513513

514+
public function testReusesResolvedProducer()
515+
{
516+
$this->bindProducerToApp($producer = $this->getProducerMock($this->connection));
517+
518+
$producer->expects($this->exactly(2))->method('publishBatch');
519+
520+
$amqp = $this->getAmqpInstance(null, ['exchange' => ['name' => self::EXCHANGE_NAME, 'type' => 'topic']]);
521+
$amqp->publish(
522+
'my message',
523+
'my-binding-key',
524+
$data['exchange'] ?? null,
525+
$data['options'] ?? []
526+
);
527+
528+
// Bind new producer to the container
529+
$this->bindProducerToApp($producer2 = $this->getProducerMock($this->connection));
530+
// This producer should never be called as the previous producer is already stored in the class.
531+
$producer2->expects($this->never())->method('publishBatch');
532+
533+
$amqp->publish(
534+
'my another message',
535+
'my-binding-key',
536+
$data['exchange'] ?? null,
537+
$data['options'] ?? []
538+
);
539+
}
540+
514541
public function testConsumeHandlerIsChangesCallableToConsumable()
515542
{
516543
$this->bindConsumerToApp($consumer = $this->getConsumerMock($this->connection));
@@ -563,7 +590,7 @@ function () {
563590
/**
564591
* @dataProvider exchangeTestDataProvider
565592
*
566-
* @param array $data
593+
* @param array $data
567594
*/
568595
public function testConsumerProcessesExchange(array $data)
569596
{
@@ -611,7 +638,7 @@ function () {
611638
/**
612639
* @dataProvider queueTestDataProvider
613640
*
614-
* @param array $data
641+
* @param array $data
615642
*/
616643
public function testConsumerProcessesQueue(array $data)
617644
{
@@ -659,7 +686,7 @@ function () {
659686
/**
660687
* @dataProvider qosTestDataProvider
661688
*
662-
* @param array $data
689+
* @param array $data
663690
*/
664691
public function testConsumerProcessesQos(array $data)
665692
{
@@ -714,7 +741,7 @@ function () {
714741
/**
715742
* @dataProvider queueBindTestDataProvider
716743
*
717-
* @param array $data
744+
* @param array $data
718745
*/
719746
public function testConsumerProcessesQueueBind(array $data)
720747
{
@@ -762,7 +789,7 @@ function () {
762789
/**
763790
* @dataProvider consumerConfigTestDataProvider
764791
*
765-
* @param array $data
792+
* @param array $data
766793
*/
767794
public function testConsumerProcessesConsumerConfig(array $data)
768795
{

0 commit comments

Comments
 (0)