Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Redis Messenger Laravel Package

symfony/redis-messenger

Redis transport integration for Symfony Messenger, enabling queueing and async message handling backed by Redis. Part of the Symfony ecosystem, with links to contributing, issue reporting, and pull requests in the main Symfony repository.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Package:

    composer require symfony/redis-messenger
    

    Ensure ext-redis is enabled in your PHP environment (PHP 8.1+ recommended).

  2. Configure Redis Transport: Add to your Laravel config/messenger.php (or Symfony config/packages/messenger.yaml if hybrid):

    'transports' => [
        'redis' => [
            'dsn' => 'redis://127.0.0.1:6379',
            'options' => [
                'prefix' => 'messenger_', // Avoid key collisions
                'read_write_timeout' => 2.0,
            ],
        ],
    ],
    

    For Sentinel/Cluster (e.g., AWS ElastiCache):

    'dsn' => 'redis+sentinel://user:pass@host1:26379,host2:26379/mydb?auth=pass&alias=master',
    
  3. Dispatch a Message: Create a Symfony Message class (e.g., app/Messages/ProcessOrder.php):

    namespace App\Messages;
    
    class ProcessOrder {
        public function __construct(public string $orderId) {}
    }
    

    Dispatch via Laravel’s Bus facade (or Symfony’s MessageBus):

    use Illuminate\Support\Facades\Bus;
    Bus::dispatch(new ProcessOrder('order_123'));
    
  4. Consume Messages: Run the Symfony worker (replace redis with your transport name):

    php bin/console messenger:consume redis -vv
    

    Or integrate with Laravel’s queue system (see Implementation Patterns).


First Use Case: Offloading Email Sending

  1. Create a handler:
    namespace App\Handlers;
    
    use App\Messages\SendWelcomeEmail;
    use Symfony\Component\Messenger\Attribute\AsMessageHandler;
    
    #[AsMessageHandler]
    class SendWelcomeEmailHandler {
        public function __invoke(SendWelcomeEmail $message) {
            Mail::to($message->email)->send(new WelcomeEmail($message->user));
        }
    }
    
  2. Dispatch:
    Bus::dispatch(new SendWelcomeEmail($user->email, $user));
    
  3. Profit: Your API responds instantly while emails are processed asynchronously.

Key Starting Points

  • Symfony Messenger Docs: Core concepts (handlers, buses, transports).
  • Redis Transport Docs: Configuration options.
  • Laravel Integration: Use symfony/messenger + symfony/redis-messenger with Laravel’s Bus facade or a custom Queue adapter.

Implementation Patterns

1. Laravel-Symfony Hybrid Workflow

Leverage Laravel’s Bus facade while using Symfony’s Redis transport:

// config/messenger.php
'transports' => [
    'redis' => [
        'dsn' => env('REDIS_DSN'),
        'options' => [
            'prefix' => 'laravel_messenger_',
        ],
    ],
],

// Dispatch via Laravel
Bus::dispatch(new ProcessPayment($orderId));

// Consume via Symfony CLI (or Laravel Artisan)
php artisan messenger:consume redis --limit=10

Pro Tip: Create a Laravel Queue adapter for Symfony’s MessageBus to reuse Laravel’s queue workers:

// app/Providers/AppServiceProvider.php
use Symfony\Component\Messenger\MessageBus;
use Symfony\Component\Messenger\Transport\Serialization\SerializerInterface;

public function register()
{
    $this->app->singleton('symfony.message_bus', function ($app) {
        $bus = new MessageBus([
            new RedisTransport(
                Redis::connection('default'),
                new Serializer(),
                'redis'
            ),
        ]);
        return $bus;
    });
}

2. Message Routing & Prioritization

Use Symfony’s routing keys to prioritize messages:

# config/packages/messenger.yaml
framework:
    messenger:
        transports:
            redis:
                dsn: '%env(REDIS_DSN)%'
                options:
                    queues:
                        high: 'high_priority'
                        normal: 'normal_priority'
                        low: 'low_priority'
        routing:
            'App\Messages\ProcessOrder': high
            'App\Messages\SendEmail': normal
            'App\Messages\LogAnalytics': low

Laravel Integration:

// Dispatch to a specific queue
Bus::dispatch(new ProcessOrder($orderId))->setQueue('high');

3. Retry & Failure Handling

Configure retries in config/messenger.php:

'failure_transport' => 'failed',
'failed_message_transport' => 'doctrine', // or 'redis' for dead-letter queue
'retries' => 3,
'retry_strategy' => [
    'max_tries' => 3,
    'delay' => 1000, // 1 second
    'multiplier' => 2, // exponential backoff
    'max_delay' => 0, // no max delay
],

Dead-Letter Queue (DLQ):

// config/messenger.php
'transports' => [
    'failed' => [
        'dsn' => 'redis://127.0.0.1:6379/1',
        'options' => ['queue_name' => 'failed_messages'],
    ],
],

4. Worker Scaling & Concurrency

Run multiple workers for parallel processing:

# Terminal 1: High-priority queue
php artisan messenger:consume redis --queue=high --limit=5

# Terminal 2: Normal queue
php artisan messenger:consume redis --queue=normal --limit=10

# Terminal 3: Low-priority queue
php artisan messenger:consume redis --queue=low --limit=20

Dynamic Scaling: Use a process manager like Supervisor or Docker Compose to auto-scale workers based on queue depth.


5. Pub/Sub for Real-Time Updates

Use Redis pub/sub for event-driven architectures:

// Publisher (e.g., after order processing)
Redis::connection()->publish('order_events', json_encode([
    'event' => 'order.processed',
    'order_id' => $orderId,
]));

// Subscriber (Symfony Messenger handler)
#[AsMessageHandler]
class OrderEventSubscriber {
    public function __invoke(OrderEvent $event) {
        // Broadcast to WebSocket clients, etc.
    }
}

Laravel Integration: Pair with laravel-echo for real-time updates.


6. Testing Strategies

Unit Testing Handlers:

use Symfony\Component\Messenger\Test\MessageBusInterface;

public function testProcessOrder()
{
    $bus = $this->createMock(MessageBusInterface::class);
    $bus->expects($this->once())
        ->method('dispatch')
        ->with($this->isInstanceOf(ProcessOrder::class));

    $handler = new ProcessOrderHandler($bus);
    $handler(new ProcessOrder('order_123'));
}

Integration Testing: Use Symfony’s TransportTestCase:

use Symfony\Component\Messenger\Transport\Serialization\SerializerInterface;
use Symfony\Component\Messenger\Transport\RedisExtTransport;

public function testRedisTransport()
{
    $redis = Redis::connection();
    $transport = new RedisExtTransport($redis, new Serializer(), 'test');
    $this->assertTrue($transport->isStarted());
}

Gotchas and Tips

Pitfalls & Debugging

  1. Duplicate Messages:

    • Cause: Redis transport may reprocess messages if workers crash mid-execution.
    • Fix: Use Symfony’s TransportMessageIdStamp (enabled by default) or implement idempotency in handlers.
    • Workaround: Add a unique_id field to messages and track processed IDs in Redis:
      Redis::connection()->sAdd('processed_messages', $message->getMessageId());
      
  2. Connection Issues:

    • Symptom: Workers hang or fail with RedisException.
    • Debug:
      • Check Redis server logs (redis-cli monitor).
      • Verify DSN format (e.g., redis://user:pass@host:port/db).
      • For Sentinel: Ensure auth and alias are correctly configured.
    • Fix: Add retry logic to the worker or use Symfony’s KeepaliveReceiverInterface:
      use Symfony\Component\Messenger\Transport\Serialization\SerializerInterface;
      use Symfony\Component\Messenger\Transport\RedisExtTransport;
      
      $transport = new RedisExtTransport(
          Redis::connection(),
          new Serializer(),
          'redis',
          new KeepaliveReceiver()
      );
      
  3. Message Serialization:

    • Issue: Complex objects (e.g., Laravel models) may not serialize/
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity