{"id":15029064,"url":"https://github.com/phpmessagebus/eventbus-queue","last_synced_at":"2025-04-09T20:32:43.787Z","repository":{"id":57027215,"uuid":"55956828","full_name":"PHPMessageBus/eventbus-queue","owner":"PHPMessageBus","description":"Event Bus asynchronous queuing with many Producer and Consumer implementations","archived":false,"fork":false,"pushed_at":"2017-04-16T17:53:11.000Z","size":49,"stargazers_count":11,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-03-23T22:26:22.063Z","etag":null,"topics":["amqp","amqp-queue","beanstalkd","consumer","event-driven","event-driven-microservices","event-driven-programming","event-sourcing","eventbus","eventbus-queue","middleware","php","php7","producer","producer-consumer","queue","rabbitmq","redisqueue","supervisor"],"latest_commit_sha":null,"homepage":"http://nilportugues.com","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PHPMessageBus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-04-11T08:56:31.000Z","updated_at":"2023-01-17T20:45:55.000Z","dependencies_parsed_at":"2022-08-23T16:30:12.153Z","dependency_job_id":null,"html_url":"https://github.com/PHPMessageBus/eventbus-queue","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PHPMessageBus%2Feventbus-queue","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PHPMessageBus%2Feventbus-queue/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PHPMessageBus%2Feventbus-queue/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PHPMessageBus%2Feventbus-queue/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PHPMessageBus","download_url":"https://codeload.github.com/PHPMessageBus/eventbus-queue/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248107677,"owners_count":21048978,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["amqp","amqp-queue","beanstalkd","consumer","event-driven","event-driven-microservices","event-driven-programming","event-sourcing","eventbus","eventbus-queue","middleware","php","php7","producer","producer-consumer","queue","rabbitmq","redisqueue","supervisor"],"created_at":"2024-09-24T20:09:40.210Z","updated_at":"2025-04-09T20:32:43.747Z","avatar_url":"https://github.com/PHPMessageBus.png","language":"PHP","readme":"# EventBus Queue\n\n[![Build Status](https://travis-ci.org/PHPMessageBus/eventbus-queue.svg?branch=master)](https://travis-ci.org/PHPMessageBus/eventbus-queue) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/PHPMessageBus/eventbus-queue/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/PHPMessageBus/eventbus-queue/?branch=master) [![SensioLabsInsight](https://insight.sensiolabs.com/projects/3e4f3e13-a8c1-4f1e-a5ad-42e799915dfe/mini.png?gold)](https://insight.sensiolabs.com/projects/3e4f3e13-a8c1-4f1e-a5ad-42e799915dfe) [![Latest Stable Version](https://poser.pugx.org/nilportugues/eventbus-queue/v/stable?)](https://packagist.org/packages/nilportugues/eventbus-queue) [![Total Downloads](https://poser.pugx.org/nilportugues/eventbus-queue/downloads?)](https://packagist.org/packages/nilportugues/eventbus-queue) [![License](https://poser.pugx.org/nilportugues/eventbus-queue/license?)](https://packagist.org/packages/nilportugues/eventbus-queue)\n[![Donate](https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif)](https://paypal.me/nilportugues)\n \n - [Installation](#installation)\n - [Usage](#usage)\n    -  [ProducerEventBus](#producereventbus)\n    -  [Consumer for the ProducerEventBus](#consumer-for-the-producereventbus)\n    -  [EventBusWorker](#eventbusworker)\n - [Adapter Configurations](#adapter-configurations)\n    - [PDOQueue](#pdoqueue)\n    - [MongoDBQueue](#mongodbqueue)\n    - [RedisQueue](#redisqueue)\n    - [PredisQueue](#predisqueue)\n    - [FileSystemQueue](#filesystemqueue)\n    - [AmqpQueue](#amqpqueue)\n    - [BeanstalkdQueue](#beanstalkdqueue)\n - [Contribute](#contribute)\n - [Support](#support)\n - [Authors](#authors)\n - [License](#license)\n\nThis package is an extension library for **[nilportugues/messagebus](http://github.com/PHPMessageBus/messagebus)**, adding queues to the EventBus implementation.\n\nThis package will provide you for the classes necessary to build:\n \n- **The Producer**: code that sends the Event to a Queue by serializing the Event. This happens synchronously.\n- **The Consumer**: code that reads in the background, therefore asynchronously, reads and unserializes the Event from the Queue and passes it to the EventBus to do the heavy lifting.\n\n\n## Why? \n\nIt's all about deciding which command logic can be delayed, or hidden away in order to make it faster. And this is what we want to do.\n\n**You never remove a bottleneck, you just move it.** The downside is that we might have to assume a possible delay.\n\n## Installation\n\nIn order to start using this project you require to install it using [Composer](https://getcomposer.org):\n\n```\ncomposer require nilportugues/eventbus-queue\n```\n\n## Usage\n\nThis package will provide you with a new middleware: `ProducerEventBusMiddleware`.   \n\nThis middleware requires a serializer and a storage that will depend on the Queue Adapter used. Supported adapters are: \n\n- **PDOQueue**: queue built with a SQL database using Doctrine's DBAL.\n- **MongoDBQueue**: queue built with MongoDB library.\n- **RedisQueue**: queue using the Redis PHP extension.\n- **PredisQueue**: queue using the Predis library.\n- **FileSystemQueue**: queue built with using the local file system.\n- **AmqpQueue**: use RabbitMQ or any queue implementing the Amqp protocol.\n- **BeanstalkdQueue**: use Beanstalk as queue.\n\nTo set it up, register the `ProducerEventBusMiddleware` to the Event Bus. Because we'll need to define a second EventBus (consumer), we'll call this the `ProducerEventBus`.\n\n#### ProducerEventBus\n\n```php\n\u003c?php\n$container['LoggerEventBusMiddleware'] = function() use ($container) {\n    return new \\NilPortugues\\MessageBus\\EventBus\\LoggerEventBusMiddleware(\n        $container['Monolog']\n    );\n};\n\n//Definition of the Serializer\n$container['NativeSerializer'] = function() use ($container) {\n    return new \\NilPortugues\\MessageBus\\Serializer\\NativeSerializer();\n};\n\n//Definition of the Queue driver\n$container['RabbitMQ'] = function() use ($container) {\n    return new AMQPStreamConnection('127.0.0.1', 5672, 'guest', 'guest');\n};\n\n//Definition of the Event Bus Queue. For instance RabbitMQ.\n$container['EventBusQueueAdapter'] = function() use ($container) {\n    return new \\NilPortugues\\MessageBus\\EventBusQueue\\Adapters\\AmqpQueue(\n        $container['NativeSerializer'],\n        $container['RabbitMQ'],\n        'myEventBusQueue' //queue Name\n    );\n};\n\n//Definition of the Producer.\n$container['ProducerEventBusMiddleware'] = function() use ($container) {\n    return new \\NilPortugues\\MessageBus\\EventBusQueue\\ProducerEventBusMiddleware(\n        $container['EventBusQueueAdapter']\n    );\n};\n\n//This is our ProducerEventBus. \n$container['ProducerEventBus'] = function() use ($container) {\n    return new \\NilPortugues\\MessageBus\\EventBus\\EventBus([\n        $container['LoggerEventBusMiddleware'],\n        $container['ProducerEventBusMiddleware']\n    ]);\n};\n```\n\n#### Consumer for the ProducerEventBus\n\nThe Consumer will need to be a script that reads the EventBus definitions and subscribed events in order to run until all events are handled. To do so, we'll need to register a new `EventBus` we'll refer as `ConsumerEventBus`. \n\nWe will also like to store events that could not be handled or raised an exception. So a new Queue will be required. For instance, let's store errors in a MongoDB database.\n\nThis could be as simple as follows:\n\n```php\n\u003c?php\n//This is our ConsumerEventBus. \n$container['ConsumerEventBus'] = function() use ($container) {\n    return new \\NilPortugues\\MessageBus\\EventBus\\EventBus([\n        $container['LoggerEventBusMiddleware'],\n        $container['EventBusMiddleware'],\n    ]);\n};\n\n$container['MongoDB'] = function() use ($container) {\n    return new \\MongoDB\\Client();\n};\n\n//This is an error Queue.\n$container['ErrorQueue'] = function() use ($container) {\n    return new \\NilPortugues\\MessageBus\\EventBusQueue\\Adapters\\MongoQueue(\n        $container['NativeSerializer'],\n        $container['MongoDB'], \n        'error_queues', \n        'myEventBusErrorQueue'\n     );\n};\n\n```\n\n#### EventBusWorker\n\nFinally, we'll have to call a consumer. This package already provides a fully working consumer implementation: `EventBusWorker`.\n\nUse it as follows:\n\n```php\n\u003c?php\n//... your $container should be available here.\n\n$consumer = \\NilPortugues\\MessageBus\\EventBusQueue\\EventBusWorker();\n$consumer-\u003econsume(\n    $container-\u003eget('EventBusQueueAdapter'), \n    $container-\u003eget('ErrorQueue'), \n    $container-\u003eget('ConsumerEventBus')\n);\n```\n\nConsumer class will run the `consume` method until all events are consumed. Then it will exit. This is optimal to make sure it will not leak memory.\n\nIf you need to keep the consumer running forever use server scripts like [Supervisor](http://supervisord.org/). \n\n#### Supervisor Configuration\n\nSupervisor is a process monitor for the Linux operating system, and will automatically restart your workers if they fail. To install Supervisor on Ubuntu, you may use the following command:\n\n```sh\nsudo apt-get install supervisor\n```\n\nSupervisor configuration files are typically stored in the `/etc/supervisor/conf.d` directory. Within this directory, you may create any number of configuration files that instruct how your processes should be monitored. \n\nFor instance, let's create `/etc/supervisor/conf.d/my_worker.conf` so that it starts and monitors a worker script named `my_worker.php`:\n\n```ini\n[program:my_worker]\nprocess_name=%(program_name)s_%(process_num)02d\ncommand=php my_worker.php\nautostart=true\nautorestart=true\nuser=www-data\nnumprocs=20\nredirect_stderr=true\nstdout_logfile=/var/log/my_worker.log\n```\n\nIn this file, we tell Supervisor that we want 20 instances always running. If the `my_worker.php` ends or fails it will spin up a new one.\n\nIn order to make this task run forever, you'll have to type in the following commands: \n\n```sh\nsudo supervisorctl reread\nsudo supervisorctl update\nsudo supervisorctl start my_worker\n```\n\n## Adapter Configurations\n\n#### PDOQueue\n\nFor this to work, you'll be required to create a table in your database. \n\nFor instance, sqlite dialect table creation would be: \n\n```sql\nCREATE TABLE testAdapterQueue (\n  id INTEGER PRIMARY KEY AUTOINCREMENT,\n  event_data TEXT NOT NULL,\n  event_status CHAR(50),\n  created_at INTEGER NOT NULL\n);\n```\n\n#### MongoDBQueue\n\nIn order to use it, you require to install PHP 7's mongodb extension. \n\n```\nsudo pecl install mongodb\n```\n\n#### RedisQueue\n\nIn order to use it, you require to install PHP 7's phpredis extension. \n\n```\n# Build Redis PHP module\ngit clone -b php7 https://github.com/phpredis/phpredis.git\nsudo mv phpredis/ /etc/ \u0026\u0026 \\\ncd /etc/phpredis \\\nphpize \\\n./configure \\\nmake \u0026\u0026 make install \\\ntouch /etc/php/7.0/mods-available/redis.ini \\\necho 'extension=redis.so' \u003e /etc/php/7.0/mods-available/redis.ini\n```\n\n#### PredisQueue\n\nNothing, but performs better if phpredis extension is found.\n\n#### FileSystemQueue\n\nNothing to do. \n\n#### AmqpQueue\n\nNothing to do other than having access to a amqp server.\n\n#### Beanstalkd\n\nNothing to do other than having access to a beanstalkd server.\n\n## Contribute\n\nContributions to the package are always welcome!\n\n* Report any bugs or issues you find on the [issue tracker](https://github.com/PHPMessageBus/event-bus-queue/issues/new).\n* You can grab the source code at the package's [Git repository](https://github.com/PHPMessageBus/event-bus-queue).\n\n\n## Support\n\nGet in touch with me using one of the following means:\n\n - Emailing me at \u003ccontact@nilportugues.com\u003e\n - Opening an [Issue](https://github.com/PHPMessageBus/event-bus-queue/issues/new)\n\n\n## Authors\n\n* [Nil Portugués Calderó](http://nilportugues.com)\n* [The Community Contributors](https://github.com/PHPMessageBus/event-bus-queue/graphs/contributors)\n\n\n## License\nThe code base is licensed under the [MIT license](LICENSE).\n","funding_links":["https://paypal.me/nilportugues"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphpmessagebus%2Feventbus-queue","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphpmessagebus%2Feventbus-queue","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphpmessagebus%2Feventbus-queue/lists"}