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

Doctrine Messenger Laravel Package

symfony/doctrine-messenger

Doctrine integration for Symfony Messenger. Store, dispatch, and consume messages using Doctrine-backed transports and tooling. Part of the Symfony ecosystem; issues and contributions go through the main Symfony repository.

View on GitHub
Deep Wiki
Context7

Getting Started

For Laravel developers, this package is not directly applicable—it is a Symfony-specific bridge. However, if you're working in a Symfony/Laravel hybrid or need a Doctrine-backed message transport, here’s how to approach it:

Minimal Setup (Symfony Context)

  1. Install the package:
    composer require symfony/doctrine-messenger
    
  2. Configure in config/packages/messenger.yaml:
    framework:
        messenger:
            transports:
                doctrine_transport: 'doctrine://default'
            routing:
                'App\Message\YourMessage': doctrine_transport
    
  3. Create the transport table:
    php bin/console doctrine:messenger:setup-transport
    
  4. Dispatch a message:
    use Symfony\Component\Messenger\MessageBusInterface;
    
    public function __construct(private MessageBusInterface $bus) {}
    
    public function sendMessage(): void
    {
        $this->bus->dispatch(new YourMessage());
    }
    

Laravel Workaround (Indirect Use)

If you must use Doctrine in Laravel (e.g., for legacy systems), you could:

  1. Use symfony/messenger + symfony/doctrine-messenger in a Symfony microkernel alongside Laravel.
  2. Expose Symfony’s Messenger bus to Laravel via a custom service provider:
    // app/Providers/SymfonyMessengerServiceProvider.php
    public function register()
    {
        $this->app->singleton(MessageBusInterface::class, function ($app) {
            return require __DIR__.'/../../vendor/symfony/messenger/MessageBus.php';
        });
    }
    
  3. Manually create the transport table via a Laravel migration (Doctrine schema won’t auto-generate).

Implementation Patterns

1. Transport Configuration

  • Single-table multi-queue: Use queue_name to partition messages:
    transports:
        orders: 'doctrine://default?queue_name=orders'
        notifications: 'doctrine://default?queue_name=notifications'
    
  • Retry logic: Leverage Symfony’s retry middleware:
    framework:
        messenger:
            transports:
                async: 'doctrine://default'
            middleware:
                - 'doctrine://default?retry_strategy=exponential'
    

2. Consumer Workflows

  • Dedicated workers: Run consumers per queue:
    php bin/console messenger:consume orders --limit=10 --time-limit=300
    
  • Batch processing: Use --limit to control message throughput:
    php bin/console messenger:consume notifications --limit=50
    

3. Integration with Laravel

If bridging Symfony Messenger to Laravel:

  • Expose Symfony’s MessageBus as a Laravel service (see Getting Started).
  • Use Laravel’s queue system for most jobs, but offload complex workflows (e.g., sagas) to Symfony Messenger.
  • Shared database schema: Ensure Laravel’s queue tables (jobs) and Symfony’s (messenger_message) don’t conflict.

4. Event-Driven Patterns

  • Listen for message events (e.g., MessageSentToTransportEvent):
    use Symfony\Component\Messenger\Event\SentToTransportEvent;
    
    $bus->dispatch(new YourMessage(), [new SentToTransportEventListener()]);
    

Gotchas and Tips

Pitfalls

  1. Database Locking:

    • Doctrine Messenger uses optimistic locking (via locked_at column). Long-running consumers may cause deadlocks.
    • Fix: Use --time-limit to avoid holding locks too long.
  2. Schema Mismatches:

    • Laravel’s jobs table and Symfony’s messenger_message table cannot coexist without conflicts.
    • Workaround: Use separate databases or namespaces (e.g., symfony_messenger_message).
  3. Transaction Isolation:

    • Doctrine Messenger assumes serializable transactions for reliability. MySQL’s default REPEATABLE READ may cause issues.
    • Fix: Configure isolation_level=serializable in your DBAL connection.
  4. PostgreSQL-Specific Quirks:

    • Uses LISTEN/NOTIFY for real-time consumption. If using connection pooling, ensure the pool reuses the same backend PID.
    • Fix: Configure pgsql.notification_queue_size or use pg_notify() explicitly.
  5. PHP 8.5+ Deprecations:

    • pgsql_get_notify() is deprecated. Symfony 8.1+ uses pg_notify() instead.
    • Fix: Update to the latest Symfony Messenger version.

Debugging Tips

  • Check transport status:
    php bin/console messenger:failed-messages-list
    php bin/console messenger:consume doctrine_transport --debug
    
  • Enable SQL logging in Doctrine to inspect queries:
    doctrine:
        dbal:
            logging: true
            profiling: true
    
  • Monitor locks: Query SELECT * FROM messenger_message WHERE locked_at IS NOT NULL to find stuck messages.

Extension Points

  1. Custom Transport: Extend DoctrineTransport to add features (e.g., priority queues):
    class PriorityDoctrineTransport extends DoctrineTransport
    {
        protected function getMessageTable(): string
        {
            return 'priority_messenger_message';
        }
    }
    
  2. Middleware: Add custom logic (e.g., logging, metrics):
    framework:
        messenger:
            middleware:
                - 'App\Middleware\LogMessageMiddleware'
    
  3. Schema Customization: Override the default schema via DoctrineTransportFactory:
    $factory = new DoctrineTransportFactory();
    $factory->setSchema([
        'message' => 'custom_messenger_message',
        'failed_message' => 'custom_messenger_failed_message',
    ]);
    

Laravel-Specific Gotchas

  • Service Container Conflicts: Symfony’s EventDispatcher and Laravel’s Dispatcher will clash. Use a proxy pattern to bridge them.
  • Queue Workers: Symfony’s messenger:consume cannot replace Laravel’s queue:work. Run them in parallel or migrate entirely.
  • Job Serialization: Symfony Messenger uses native PHP serialization. If your jobs rely on Laravel’s ShouldQueue traits, ensure they’re serializable.

Performance Tips

  • Batch inserts: Doctrine Messenger batches messages by default (configurable via batch_size).
  • Indexing: Add indexes to message_id, queue_name, and locked_at for large queues.
  • Connection pooling: For PostgreSQL, use pgsql.persistent to avoid reconnect overhead.
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.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope