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

1.0.0 2025-12-31 04:05 UTC

This package is auto-updated.

Last update: 2025-12-31 04:06:11 UTC


README

Framework agnostic PHP library for publishing and consuming jobs using Redis and ElasticMQ/SQS backends.

Qatar: कतार (Queue)

Latest Version Build Status Downloads PHP Version License

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 (predis or aws-sdk-php) are suggested and must be installed separately.

Requirements

  • PHP 8.2 or higher
  • Redis server + PhpRedis OR predis/predis (for RedisQueue)
  • ElasticMQ or AWS SQS + aws/aws-sdk-php (for ElasticMQQueue)
  • 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(): Returns 3
  • delay(): Returns 60 seconds
  • failed(): 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 MONITOR or LLEN qatar:default:ready.
  • ElasticMQ: Visit http://localhost:9325 for the stats UI.

Testing

Run tests with code coverage:

./vendor/bin/phpunit

License

MIT License. See LICENSE for details.

Author

Vaibhav Pandey