vaibhavpandeyvpz / qatar
Framework agnostic PHP library for publishing and consuming jobs using Redis and ElasticMQ backends.
Installs: 0
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/vaibhavpandeyvpz/qatar
Requires
- php: ^8.2
Requires (Dev)
- aws/aws-sdk-php: ^3.0
- phpunit/phpunit: ^10.0
- predis/predis: ^2.0
Suggests
- ext-json: Required for job payload serialization
- ext-redis: Required to use RedisQueue with native driver
- aws/aws-sdk-php: Required to use ElasticMQQueue (^3.0)
- predis/predis: Required to use RedisQueue with Predis driver (^2.0)
README
Framework agnostic PHP library for publishing and consuming jobs using Redis and ElasticMQ/SQS backends.
Qatar:
कतार(Queue)
Features
- 🚀 Fast: Efficient job processing with Redis or ElasticMQ/SQS backends
- 🔄 Reliable: Automatic retries with configurable delays
- ⏰ Delayed Jobs: Schedule jobs to run in the future
- 👷 Multiple Workers: Run multiple workers concurrently
- 🎯 Simple API: Clean, intuitive interface for job management
- 🔧 Flexible: Framework agnostic - use with any PHP application
- 📝 Type-safe: Full PHP 8.2+ type hints and modern language features
- ⚡ Graceful Shutdown: Workers handle termination signals properly
- 💾 Two Backends: Choose between Redis (fast) or ElasticMQ/SQS (distributed).
- Note: Backend-specific drivers (
predisoraws-sdk-php) are suggested and must be installed separately.
- Note: Backend-specific drivers (
Requirements
- PHP 8.2 or higher
- Redis server + PhpRedis OR
predis/predis(forRedisQueue) - ElasticMQ or AWS SQS +
aws/aws-sdk-php(forElasticMQQueue) - JSON extension (
ext-json) for payload serialization (usually enabled by default)
Installation
Install via Composer:
composer require vaibhavpandeyvpz/qatar
Local Development Setup
For local testing, use Docker Compose to run Redis and ElasticMQ:
# Start services docker-compose up -d # Verify services are running docker-compose ps # Run tests ./vendor/bin/phpunit
This will start:
- Redis on
localhost:6379 - ElasticMQ on
localhost:9324(SQS-compatible API) - ElasticMQ UI on
localhost:9325(monitoring)
Quick Start
Creating a Job
Implementing Qatar\Job is simple:
<?php use Qatar\Job; class SendEmailJob extends Job { public function handle(array $payload): void { // $payload has data passed during push() mail($payload['to'], $payload['subject'], $payload['body']); } }
By extending Job, you get default implementations for:
retries(): Returns3delay(): Returns60secondsfailed(): Empty handler
Override them as needed:
class SendEmailJob extends Job { public function handle(array $payload): void { ... } public function failed(\Throwable $exception, array $payload): void { // Handle permanent failure } public function retries(): int { return 5; } }
Publishing Jobs
use Qatar\RedisQueue; // Create a Redis client (Predis or PhpRedis) $redis = new Predis\Client('tcp://127.0.0.1:6379'); // Create a queue instance $queue = new RedisQueue($redis, 'emails'); // Basic push $queue->push(SendEmailJob::class, [ 'to' => 'user@example.com', 'subject' => 'Hello!', 'body' => 'Welcome to Qatar.', ]); // Delayed push (5 minutes) $queue->push(SendEmailJob::class, [...], delay: 300);
Running Workers
use Qatar\Worker; use Qatar\RedisQueue; $redis = new Predis\Client('tcp://127.0.0.1:6379'); $queue = new RedisQueue($redis, 'emails'); $worker = new Worker($queue); $worker->work();
API Reference
Qatar\Queue Interface
| Method | Description |
|---|---|
push(string $job, array $payload, ?int $delay = null): string |
Add a job to the queue. Returns job ID. |
pop(?int $timeout = null): ?JobPayload |
Retrieve next job. Optionally wait for $timeout seconds. |
ack(string $id): bool |
Acknowledge successful completion of a job. |
nack(string $id, ?int $delay = null): bool |
Record a failure and schedule a retry. |
size(): int |
Get total number of pending and delayed jobs. |
purge(): void |
Clear all jobs from the queue. |
Qatar\Worker Class
The worker executes jobs from a queue. It is not final, so you can extend it to override resolveJob() for dependency injection.
use Qatar\Worker; use Qatar\Job; class ContainerWorker extends Worker { protected function resolveJob(string $jobClass, array $payload): Job { // Use your DI container here return $this->container->get($jobClass); } }
WorkerOptions
| Option | Default | Description |
|---|---|---|
sleep |
3 |
Seconds to wait when the queue is empty. |
maxJobs |
null |
Max number of jobs to process before stopping. |
maxTime |
null |
Max seconds to run before stopping. |
memory |
128 |
Memory limit in MB. Worker stops if exceeded. |
stopOnEmpty |
false |
If true, worker quits when queue is empty. |
Advanced Usage
Exponential Backoff
Implement custom backoff logic by using the attempts property in the payload:
class BackoffJob extends Job { public function handle(array $payload): void { // The attempt number is managed by the queue backend } public function retries(): int { return 5; } public function delay(): int { // Custom logic here return 60; } }
Redis SSL/TLS Support
The RedisQueue supports secure connections over SSL/TLS. You can use the rediss:// or tls:// schemes in your connection string:
$queue = new RedisQueue('rediss://your-secure-redis-host:6379');
When using ext-redis, the library automatically handles the tls:// prefix requirement for secure connections.
Signal Handling
Workers gracefully stop when they receive SIGTERM or SIGINT. They finish the current job before exiting.
Monitoring
- Redis: Use
redis-cli MONITORorLLEN qatar:default:ready. - ElasticMQ: Visit
http://localhost:9325for the stats UI.
Testing
Run tests with code coverage:
./vendor/bin/phpunit
License
MIT License. See LICENSE for details.
Author
Vaibhav Pandey
- GitHub: @vaibhavpandeyvpz