Skip to content

Commit

Permalink
Issue #132: Use amqp-ext as a transport (#133)
Browse files Browse the repository at this point in the history
* Issue #132: Use amqp-ext as a transport

* add enqueue/amqp-ext to suggestions

* Add laravel 11 dependencies for separate components
  • Loading branch information
eugene-nuwber committed Apr 29, 2024
1 parent a2b387a commit ed48d33
Show file tree
Hide file tree
Showing 12 changed files with 97 additions and 18 deletions.
21 changes: 21 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
ARG VERSION=8-cli
FROM php:${VERSION}-alpine

COPY --from=mlocati/php-extension-installer /usr/bin/install-php-extensions /usr/bin/
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
ENV COMPOSER_ALLOW_SUPERUSER=1

RUN install-php-extensions \
bcmath \
sockets \
pcntl \
amqp

WORKDIR /var/www/rabbitevents
ADD . .

RUN composer install -o
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ Once again, the RabbitEvents library helps you publish an event and handle it in
1. [Publisher component](#publisher)
1. [Listener component](#listener)
1. [Examples](./examples)
1. [Speeding up RabbitEvents](#speeding-up-rabbitevents)
1. [Non-standard use](#non-standard-use)
1. [License](#license)

## Installation via Composer<a name="installation"></a>
You can use Composer to install RabbitEvents into your Laravel project:
Expand Down Expand Up @@ -104,6 +106,23 @@ The RabbitEvents Publisher component provides an API to publish events across th

The RabbitEvents Listener component provides an API to handle events that were published across the application structure. More information about how it works can be found on the RabbitEvents [Listener page](https://github.com/rabbitevents/listener).

## Speeding up RabbitEvents<a name="speeding-up-rabbitevents"></a>
To enhance the performance of RabbitEvents, consider installing the `php-amqp` extension along with the `enqueue/amqp-ext` package.
By doing so, RabbitEvents will utilize the `enqueue/amqp-ext` package instead of the default `enqueue/amqp-lib` package.
This substitution is advantageous because the C-written `php-amqp` package significantly outperforms the PHP-written `enqueue/amqp-lib` package.

You can install the `php-amqp` extension using the following command:
```bash
pecl install amqp
```
or use the way you prefer. More about it can be found [here](https://pecl.php.net/package/amqp).

Next, install the `enqueue/amqp-ext` package with the following command:
```bash
composer require enqueue/amqp-ext
```
No additional configuration is required.

## Non-standard use <a name="#non-standard-use"></a>

If you're using only one part of RabbitEvents, you should know a few things:
Expand All @@ -123,3 +142,7 @@ If you're using only one part of RabbitEvents, you should know a few things:

There are 3 elements in this array, so 3 variables will be passed to a Listener (an array, a string, and an integer).
If an associative array is being passed, the Dispatcher wraps this array by itself.

# License <a name="license"></a>

RabbitEvents is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@
},
"suggest": {
"ext-pcntl": "Required to use all features of the worker.",
"vlucas/phpdotenv": "Loads environment variables from .env to getenv(), $_ENV and $_SERVER automagically."
"ext-amqp": "Using this extension makes your app faster. If you're using it you need to install enqueue/amqp-ext.",
"enqueue/amqp-ext": "This package is necessary if you want to use `ext-amqp`."
},
"config": {
"sort-packages": true,
Expand Down
12 changes: 12 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: rabbitevents-dev

services:
rabbitevents:
volumes:
- ./:/var/www/rabbitevents
build:
context: .
dockerfile: Dockerfile
stdin_open: true
tty: true
working_dir: /var/www/rabbitevents
20 changes: 16 additions & 4 deletions src/RabbitEvents/Foundation/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@

namespace RabbitEvents\Foundation;

use Interop\Amqp\AmqpContext;
use Enqueue\AmqpLib\AmqpConnectionFactory;
use Enqueue\AmqpTools\DelayStrategy;
use Enqueue\AmqpTools\RabbitMqDlxDelayStrategy;
use Illuminate\Support\Arr;
use Interop\Amqp\AmqpConnectionFactory;
use Interop\Amqp\AmqpContext;
use Interop\Queue\Context;

class Connection
{
Expand Down Expand Up @@ -44,7 +45,7 @@ public function connect(): AmqpConnectionFactory
/**
* @return AmqpContext
*/
public function createContext(): AmqpContext
public function createContext(): Context
{
return $this->connect()->createContext();
}
Expand Down Expand Up @@ -88,7 +89,9 @@ public function getConfig($key = null, $default = null): mixed
*/
protected function factory(): AmqpConnectionFactory
{
$factory = new AmqpConnectionFactory([
$connectionFactoryClass = $this->getConnectionFactoryClass();

$factory = new $connectionFactoryClass([
'dsn' => $this->getConfig('dsn'),
'host' => $this->getConfig('host', '127.0.0.1'),
'port' => $this->getConfig('port', 5672),
Expand Down Expand Up @@ -116,4 +119,13 @@ protected function factory(): AmqpConnectionFactory

return $factory;
}

private function getConnectionFactoryClass(): string
{
if (extension_loaded('amqp') && class_exists('Enqueue\AmqpExt\AmqpConnectionFactory')) {
return \Enqueue\AmqpExt\AmqpConnectionFactory::class;
} else {
return \Enqueue\AmqpLib\AmqpConnectionFactory::class;
}
}
}
4 changes: 1 addition & 3 deletions src/RabbitEvents/Foundation/Consumer.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
use Illuminate\Support\Carbon;
use Interop\Amqp\AmqpConsumer;
use Interop\Amqp\AmqpMessage;
use PhpAmqpLib\Exception\AMQPRuntimeException;
use RabbitEvents\Foundation\Contracts\Transport;
use RabbitEvents\Foundation\Exceptions\ConnectionLostException;

/**
Expand Down Expand Up @@ -51,7 +49,7 @@ protected function receiveMessage(int $timeout = 0): ?AmqpMessage
{
try {
return $this->amqpConsumer->receive($timeout);
} catch (AMQPRuntimeException $exception) {
} catch (\Throwable $exception) {
throw new ConnectionLostException($exception);
}
}
Expand Down
1 change: 1 addition & 0 deletions src/RabbitEvents/Foundation/Context.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

/**
* @mixin \Enqueue\AmqpLib\AmqpContext
* @mixin \Enqueue\AmqpExt\AmqpContext
*/
class Context
{
Expand Down
13 changes: 8 additions & 5 deletions src/RabbitEvents/Foundation/composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"name": "rabbitevents/foundation",
"description": " ",
"description": "Rabbitevents common package",
"homepage": "https://github.com/rabbitevents/foundation",
"keywords": ["laravel", "rabbitmq", "events", "broadcast"],
"type": "library",
"license": "MIT",
Expand All @@ -14,9 +15,9 @@
"php": "^8.1",
"ext-bcmath": "*",
"ext-json": "*",
"illuminate/support": "^9.0|^10.0",
"illuminate/console": "^9.0|^10.0",
"illuminate/container": "^9.0|^10.0",
"illuminate/support": "9 - 11",
"illuminate/console": "^9 - 11",
"illuminate/container": "9 - 11",
"enqueue/amqp-lib": "^0.10"
},
"autoload": {
Expand All @@ -32,6 +33,8 @@
}
},
"suggest": {
"vlucas/phpdotenv": "Required to use env funciton."
"ext-pcntl": "Required to use all features of the worker.",
"ext-amqp": "Using this extension makes your app faster. If you're using it you need to install enqueue/amqp-ext.",
"enqueue/amqp-ext": "This package is necessary if you want to use `ext-amqp`."
}
}
10 changes: 10 additions & 0 deletions src/RabbitEvents/Listener/Commands/ListenCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ class ListenCommand extends Command
*/
public function handle(Context $context, Worker $worker)
{
$this->checkExtLoaded();

$this->registerLogWriters();
$this->listenForApplicationEvents();

Expand Down Expand Up @@ -166,4 +168,12 @@ private function parseLoggingConfiguration(): array
Arr::get($config, 'logging.channel'),
];
}

private function checkExtLoaded(): void
{
if (extension_loaded('amqp') && !class_exists('Enqueue\AmqpExt\AmqpConnectionFactory')) {
$this->info("You have ext-amqp extension installed. Require enqueue/amqp-ext package to use it.");
$this->info("The package can be installed via 'composer require enqueue/amqp-ext' command.");
}
}
}
4 changes: 2 additions & 2 deletions src/RabbitEvents/Listener/composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "rabbitevents/listener",
"description": "The Listener part of the RabbitEvents library.",
"description": "The Listener component of the RabbitEvents library.",
"keywords": ["laravel", "rabbitmq", "events", "listener", "sub"],
"type": "library",
"license": "MIT",
Expand All @@ -14,7 +14,7 @@
"require": {
"php": "^8.1",
"ext-json": "*",
"illuminate/events": "^9.0|^10.0",
"illuminate/events": "9 - 11",
"rabbitevents/foundation": "self.version"
},
"autoload": {
Expand Down
2 changes: 1 addition & 1 deletion src/RabbitEvents/Publisher/composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "rabbitevents/publisher",
"description": "The Publisher part of the RabbitEvents package.",
"description": "The Publisher component of the RabbitEvents package.",
"keywords": ["laravel", "rabbitmq", "events", "broadcast", "publish", "pub"],
"type": "library",
"license": "MIT",
Expand Down
2 changes: 0 additions & 2 deletions tests/Foundation/ConsumerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@
use Interop\Amqp\AmqpMessage;
use Interop\Amqp\Impl\AmqpMessage as ImplAmqpMessage;
use PhpAmqpLib\Exception\AMQPRuntimeException;
use RabbitEvents\Foundation\Connection;
use RabbitEvents\Foundation\Consumer;
use RabbitEvents\Foundation\Context;
use RabbitEvents\Foundation\Contracts\Transport;
use RabbitEvents\Foundation\Exceptions\ConnectionLostException;
use RabbitEvents\Foundation\Message;
use \Mockery as m;
Expand Down

0 comments on commit ed48d33

Please sign in to comment.