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

Messenger Bundle Laravel Package

draw/messenger-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require draw/messenger-bundle
    

    Add to config/app.php under providers:

    Draw\MessengerBundle\MessengerBundle::class,
    
  2. Publish Config

    php artisan vendor:publish --provider="Draw\MessengerBundle\MessengerBundle" --tag="config"
    

    This generates config/messenger.php with default settings (e.g., default_queue, connections, middleware).

  3. First Use Case: Dispatching a Message Define a message class (e.g., app/Messages/WelcomeUser.php):

    namespace App\Messages;
    
    class WelcomeUser
    {
        public function __construct(public string $userId) {}
    }
    

    Dispatch it in a controller or service:

    use Draw\MessengerBundle\Messenger\MessageBus;
    
    class UserController extends Controller
    {
        public function __construct(private MessageBus $bus) {}
    
        public function register()
        {
            $this->bus->dispatch(new WelcomeUser('user-123'));
        }
    }
    
  4. Configure a Queue Connection Edit config/messenger.php to define a queue (e.g., database or redis):

    'connections' => [
        'database' => [
            'driver' => 'database',
            'table' => 'jobs',
            'queue' => 'default',
        ],
    ],
    
  5. Run the Worker

    php artisan messenger:work
    

    Or use a process manager (e.g., Supervisor) for production.


Implementation Patterns

Core Workflows

  1. Message Dispatching

    • Use dependency injection for MessageBus in controllers/services.
    • Chain messages for complex workflows:
      $this->bus->dispatch(new ProcessOrder($orderId))
                ->then(new NotifyCustomer($orderId))
                ->catch(function (OrderFailedException $e) {
                    $this->bus->dispatch(new LogError($e));
                });
      
  2. Handling Messages

    • Create handlers by implementing Draw\MessengerBundle\Messenger\MessageHandlerInterface:
      class WelcomeUserHandler implements MessageHandlerInterface
      {
          public function handle(WelcomeUser $message)
          {
              // Logic to send welcome email
          }
      }
      
    • Register handlers in config/messenger.php:
      'handlers' => [
          WelcomeUser::class => [
              'handler' => App\Handlers\WelcomeUserHandler::class,
              'queue' => 'emails',
          ],
      ],
      
  3. Queue Prioritization

    • Assign queues to messages in config:
      'handlers' => [
          HighPriorityMessage::class => [
              'queue' => 'high',
          ],
      ],
      
    • Use php artisan messenger:work --queue=high to process specific queues.
  4. Middleware for Cross-Cutting Concerns

    • Add middleware to config/messenger.php:
      'middleware' => [
          \Draw\MessengerBundle\Middleware\LogMessage::class,
          \App\Middleware\ValidateUser::class,
      ],
      
    • Create custom middleware by implementing Draw\MessengerBundle\Messenger\Middleware\MiddlewareInterface.
  5. Retry Logic

    • Configure retries in config/messenger.php:
      'retry_after' => 60, // seconds
      'max_retries' => 3,
      

Integration Tips

  • Laravel Events: Bridge events to messages for gradual migration:
    Event::listen(OrderPlaced::class, function (OrderPlaced $event) {
        $bus->dispatch(new ProcessOrder($event->orderId));
    });
    
  • Testing: Use MessageBus in tests with mock handlers:
    $bus = new MessageBus([new MockHandler()]);
    $bus->dispatch(new TestMessage());
    
  • Monitoring: Log message lifecycle (dispatch/handle/fail) via middleware.

Gotchas and Tips

Pitfalls

  1. Handler Registration

    • Issue: Handlers not found if namespace is incorrect in config/messenger.php.
    • Fix: Use fully qualified class names (e.g., App\Handlers\WelcomeUserHandler).
    • Debug: Check php artisan messenger:list to verify registered handlers.
  2. Queue Connection Misconfiguration

    • Issue: Messages dispatched but never processed if the queue connection (e.g., Redis) is down.
    • Fix: Validate connection settings in config/messenger.php and test with:
      php artisan messenger:table
      
      (for database queues).
  3. Middleware Order Matters

    • Issue: Middleware may fail silently if not ordered correctly (e.g., validation before logging).
    • Fix: Define middleware in config/messenger.php in the desired execution order.
  4. Worker Process Management

    • Issue: Workers may exit unexpectedly in production (e.g., due to unhandled exceptions).
    • Fix: Use a process manager (Supervisor) with:
      [program:messenger]
      command=php /path/to/artisan messenger:work --queue=high,low
      autostart=true
      autorestart=true
      
  5. Message Serialization

    • Issue: Complex objects (e.g., with closures or resources) may fail to serialize.
    • Fix: Ensure messages are simple POPOs (Plain Old PHP Objects) with public properties.

Debugging Tips

  • Log Messages: Enable logging in config/messenger.php:

    'log' => true,
    

    Check storage/logs/laravel.log for dispatch/handle events.

  • Inspect Queues: Use Laravel’s queue tools:

    php artisan queue:failed  # List failed jobs
    php artisan queue:flush  # Clear all jobs
    
  • Handler Debugging: Add temporary logging in handlers:

    public function handle(WelcomeUser $message)
    {
        \Log::info('Handling welcome for', ['userId' => $message->userId]);
        // ...
    }
    

Extension Points

  1. Custom Message Bus Override MessageBus to add features (e.g., deduplication):

    class CustomMessageBus extends MessageBus
    {
        public function dispatch($message)
        {
            if ($this->isDuplicate($message)) {
                return false;
            }
            return parent::dispatch($message);
        }
    }
    
  2. Dynamic Handlers Use service providers to dynamically register handlers:

    public function register()
    {
        $this->app->bind(MessageHandlerInterface::class, function ($app, $params) {
            return new DynamicHandler();
        });
    }
    
  3. Queue Monitoring Extend the worker to expose metrics (e.g., via HTTP endpoint):

    // In a custom worker command
    public function handle()
    {
        $metrics = $this->getMetrics();
        file_put_contents('/tmp/messenger_metrics', json_encode($metrics));
    }
    
  4. Message Validation Add validation middleware to reject malformed messages:

    class ValidateMessage implements MiddlewareInterface
    {
        public function handle($message, Closure $next)
        {
            if (!$this->isValid($message)) {
                throw new InvalidMessageException();
            }
            return $next($message);
        }
    }
    
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.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware