{"id":19327698,"url":"https://github.com/antidot-framework/message-queue","last_synced_at":"2025-08-04T08:40:12.015Z","repository":{"id":45067532,"uuid":"272482896","full_name":"antidot-framework/message-queue","owner":"antidot-framework","description":"Message queue for Antidot Framework.","archived":false,"fork":false,"pushed_at":"2022-12-01T10:01:30.000Z","size":99,"stargazers_count":5,"open_issues_count":3,"forks_count":1,"subscribers_count":1,"default_branch":"1.x.x","last_synced_at":"2025-05-19T15:59:38.329Z","etag":null,"topics":["hacktoberfest","php","queue-workers"],"latest_commit_sha":null,"homepage":"https://queue.antidotfw.io","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/antidot-framework.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":"kpicaza"}},"created_at":"2020-06-15T15:59:43.000Z","updated_at":"2022-03-19T11:03:34.000Z","dependencies_parsed_at":"2023-01-22T14:00:55.037Z","dependency_job_id":null,"html_url":"https://github.com/antidot-framework/message-queue","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/antidot-framework/message-queue","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antidot-framework%2Fmessage-queue","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antidot-framework%2Fmessage-queue/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antidot-framework%2Fmessage-queue/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antidot-framework%2Fmessage-queue/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/antidot-framework","download_url":"https://codeload.github.com/antidot-framework/message-queue/tar.gz/refs/heads/1.x.x","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antidot-framework%2Fmessage-queue/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268671965,"owners_count":24288242,"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","status":"online","status_checked_at":"2025-08-04T02:00:09.867Z","response_time":79,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["hacktoberfest","php","queue-workers"],"created_at":"2024-11-10T02:18:11.916Z","updated_at":"2025-08-04T08:40:11.989Z","avatar_url":"https://github.com/antidot-framework.png","language":"PHP","readme":"# Antidot Framework Message Queue\n\n[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/antidot-framework/message-queue/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/antidot-framework/message-queue/?branch=master)\n[![Code Coverage](https://scrutinizer-ci.com/g/antidot-framework/message-queue/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/antidot-framework/message-queue/?branch=master)\n[![Type Coverage](https://shepherd.dev/github/antidot-framework/message-queue/coverage.svg)](https://shepherd.dev/github/antidot-framework/message-queue)\n[![Psalm Level](https://shepherd.dev/github/antidot-framework/message-queue/level.svg)](https://shepherd.dev/github/antidot-framework/message-queue)\n[![Build Status](https://scrutinizer-ci.com/g/antidot-framework/message-queue/badges/build.png?b=master)](https://scrutinizer-ci.com/g/antidot-framework/message-queue/build-status/master)\n[![Code Intelligence Status](https://scrutinizer-ci.com/g/antidot-framework/message-queue/badges/code-intelligence.svg?b=master)](https://scrutinizer-ci.com/code-intelligence)\n\nMessage queue implementation using [enqueue/enqueue](https://github.com/php-enqueue/enqueue-dev) for Antidot Framework.\n\n```bash\ncomposer require antidot-fw/message-queue\n```\n\n## Message Queue\n\n\u003e A message queue is an asynchronous communication method. It allows storing messages in the queue system until they are consumed and destroyed. \n\u003eEach message is processed only once by a unique consumer.\n\n### Different Queue Systems\n\n* Null Queue\n* Filesystem Queue\n* DBAL Queue\n* Redis Queue\n* Beanstalk\n* Amazon SQS\n\nEach implementation will have different configuration details, see concrete documentation section. Furthermore, \nyou can use any of [systems implemented in the PHP-enqueue package](https://php-enqueue.github.io/transport), making the needed factories.\n### Usage\n\nYou can define as many contexts as you need. You can bind each context to different queues.\nOnce you have created a Context class, you can start sending jobs to the queue. \nThe job should contain the queue name, the message type, and the message itself.\n\n```php\n\u003c?php\n\ndeclare(strict_types=1);\n\n/** @var \\Psr\\Container\\ContainerInterface $container */\n$producer = $container-\u003eget(\\Antidot\\Queue\\Producer::class);\n$producer-\u003eenqueue(Job::create('some_queue', 'some_message', 'Hola Mundo!!')); \n```\n\nStart listening a queue\n\n```bash\nbin/console queue:start default # \"default is the queue name\"\n```\n\nNow you can configure actions for the message types received by the queue. \nThe action is a callable class that receives a JobPayload as the first parameter.\n\n### Jobs and Producer\n\nA Job is a class responsible for transport given data to the queue. It is composed of two parameters: the Queue name as a single string, \nand the JobPayload with the data to process in the queue. JsonPayload is a JSON serializable object composed of two other parameters:\nthe message type and the message data as string or array.\n\nOnce you have a job class, you need to pass it to the producer to send the message to the queue. See the example below.\n```php\n\u003c?php\n\ndeclare(strict_types=1);\n\nuse Psr\\Container\\ContainerInterface;\nuse Antidot\\Queue\\Producer;\n\n/** @var ContainerInterface $container */\n/** @var Producer $producer */\n$producer = $container-\u003eget(Producer::class);\n\n// Send String Job of type \"some_message_type\" to \"default\" queue.\n$job1 = Job::create('default', 'some_message_type', 'Hello world!!');\n$producer-\u003eenqueue($job1);\n\n// Send Array Job of type \"other_message_type\" to \"other_queue\" queue.\n$job2 = Job::create('other_queue', 'other_message_type', ['greet' =\u003e 'Hello world!!']);\n$producer-\u003eenqueue($job2);\n\n```\n\n### Actions\n\nThe actions are invokable classes that will execute when the queue processes the given message. This class has a unique parameter, the JobPayload. \n\n```php\n\u003c?php\n\ndeclare(strict_types=1);\n\nuse Antidot\\Queue\\JobPayload;\n\nclass SomeMessageTypeAction\n{\n    public function __invoke(JobPayload $payload): void\n    {\n        // do some stuff with the job payload here.\n    }\n}\n```\n\n### Config\n\n#### Bind an action to a message type.\n\n```yaml\nservices:\n  some_action_service:\n    class: Some\\Action\\Class\nparameters:\n  queues:\n    contexts:\n      default:\n        message_types:\n          # message_type: action_service\n          some_message: some_action_service\n```\n\nThis is the default config.\n\n```yaml\nparameters:\n  queues:\n    default_context: default\n    contexts:\n      default:\n        message_types: []\n        context_type: fs # redis|dbal|sqs|beanstalk|null\n        context_service: queue.context.default\n        container: queue.container.default\n        extensions:\n          - Enqueue\\Consumption\\Extension\\LoggerExtension\n          - Enqueue\\Consumption\\Extension\\SignalExtension\n          - Enqueue\\Consumption\\Extension\\LogExtension\n```\n\n### Transport specific config\n\n#### Null Queue\n\nSo util for testing purposes, it discards any received job. The only configuration required by this transport type is to set it as context.\n\n```bash\ncomposer require enqueue/null\n```\n\n#### Filesystem Queue\n\nThe Filesystem queue stores produced jobs inside a file in memory. It requires the absolute file path to store the jobs.\n\n```bash\ncomposer require enqueue/fs\n```\n\n```yaml\nparameters:\n  queues:\n    default_context: default\n    contexts:\n      default:\n        message_types: []\n        context_type: fs\n        context_params:\n          path: file:///absoute/path/to/writable/dir\n```\n\n#### DBAL Queue\n\nThe Doctrine DBAL queue stores produced jobs inside a database. It requires the name of the DBAL connection service.\n\n```bash\ncomposer require enqueue/dbal\n```\n\n```yaml\nparameters:\n  queues:\n    default_context: default\n    contexts:\n      default:\n        message_types: []\n        context_type: dbal\n        context_params:\n          connection: Doctrine\\DBAL\\Connection\n```\n\n#### Redis Queue\n\nThe redis queue stores produced jobs inside a redis database. It requires the redis connection params.\nYou can use it with [Predis](https://github.com/nrk/predis) or with the [PHP Redis extension](https://github.com/phpredis/phpredis).\n\nWith Predis:\n  \n```bash\ncomposer require enqueue/redis predis/predis:^1\n```\n\n```yaml\nparameters:\n  queues:\n    default_context: default\n    contexts:\n      default:\n        message_types: []\n        context_type: redis\n        context_params:\n            host: localhost\n            port: 6379\n            scheme_extensions: ['predis']\n```\n\nWith PHP extension:\n \nEnsure that you have PHP Redis extension installed and enabled\n   \n```bash\ncomposer require enqueue/redis\n```\n\n```yaml\nparameters:\n  queues:\n    default_context: default\n    contexts:\n      default:\n        message_types: []\n        context_type: redis\n            host: localhost\n            port: 6379\n            scheme_extensions: ['phpredis']\n```\n\n#### Beanstalk Queue\n\nThe Beanstalk queue requires the beanstalk host and beanstalk port to work. It uses Pheanstalk PHP library.\n\n```bash\ncomposer require enqueue/pheanstalk\n```\n\n```yaml\nparameters:\n  queues:\n    default_context: default\n    contexts:\n      default:\n        message_types: []\n        context_type: beanstalk\n        context_params:\n          host: localhost\n          port: 11300\n```\n\n#### Amazon SQS Queue\n\nThe Amazon SQS queue stores produced jobs at aws. It requires the AWS console credentials. \nYou can use both [standard and FIFO queues](https://aws.amazon.com/es/sqs/) depending on your requirements. The queue must exist in AWS before sending a Job to work.\n\n```bash\ncomposer require enqueue/sqs\n```\n\n```yaml\nparameters:\n  queues:\n    default_context: default\n    contexts:\n      default:\n        message_types: []\n        context_type: sqs\n        context_params:\n          key: AWS-KEY\n          secret: AWS-SECRET\n          region: eu-west-3\n```\n\n### Consumer\n\nThe worker is the CLI command responsible for listening to the given queue to get messages and process each message one by one. \nIn this early version, the only argument that it uses is the queue name to start listening.\n\n```bash\nbin/console queue:start queue_name\n```\n\n### Events\n\nThe Antidot Framework Message Queue uses the [PSR-14 Event Dispatcher](https://www.php-fig.org/psr/psr-14/) to allow listening different instant occurred in the queue execution:\n\n* **QueueConsumeWasStarted:** Dispatches on queue start.\n* **MessageReceived:** Dispatches for any received job before process.\n* **MessageProcessed:** Dispatches after the job processed, it will have the result of the process.\n\n### Extensions\n\nSee more about extensions on [php-enqueue official docs](https://php-enqueue.github.io/consumption/extensions/)\n\n#### LogExtension\n\nYou can enable or disable debug mode logger in the framework default config. it uses PSR-3 Logger Interface internally.\n\n### Running in Production\n\nIn the production environment, you usually need a daemon to keep the consumer process alive. You can use Supervisor or any other system daemon alternative.\n\n##### Supervisor\n\nYou need to install [supervidor](http://supervisord.org/installing.html) in your system. Then you need to configure the consumer as a supervisor job.\n\n```bash\n[program:laravel-worker]\nprocess_name=%(program_name)s_%(process_num)02d\ncommand=php /absolute/path/to/app/bin/console queue:start QUEUE_NAME\nautostart=true\nautorestart=true\nuser=ubuntu\nnumprocs=2 # Be cautious, it will block your computer depending on the available simultaneous execution thread it has.\nredirect_stderr=true\nstdout_logfile=/absolute/path/to/app/var/log/worker.log\nstopwaitsecs=3600\n```\n","funding_links":["https://github.com/sponsors/kpicaza"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fantidot-framework%2Fmessage-queue","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fantidot-framework%2Fmessage-queue","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fantidot-framework%2Fmessage-queue/lists"}