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: use Doctrine-backed transports and tooling to send, store, and process messages reliably within Symfony apps. Part of the Symfony ecosystem; issues and PRs are handled in the main symfony/symfony repository.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Package

    composer require symfony/doctrine-messenger
    

    Ensure symfony/messenger and doctrine/dbal are also installed (required dependencies).

  2. Configure Doctrine Transport Add the transport to your config/packages/messenger.yaml:

    framework:
        messenger:
            transports:
                async: '%env(MESSENGER_TRANSPORT_DSN)%'
            routing:
                'App\Message\YourMessage': async
    

    Define the DSN in .env:

    MESSENGER_TRANSPORT_DSN=doctrine://default
    
  3. Run Migrations Doctrine Messenger creates tables automatically, but run:

    php bin/console doctrine:migrations:diff
    php bin/console doctrine:migrations:migrate
    
  4. Dispatch a Message

    use App\Message\YourMessage;
    use Symfony\Component\Messenger\MessageBusInterface;
    
    public function __construct(private MessageBusInterface $bus) {}
    
    public function sendMessage(): void
    {
        $this->bus->dispatch(new YourMessage('Hello, Doctrine!'));
    }
    
  5. Consume Messages Start the worker:

    php bin/console messenger:consume async -vv
    

First Use Case: Async Email Processing

  1. Create a message class:

    namespace App\Message;
    
    class SendEmailMessage {
        public function __construct(public string $email, public string $subject, public string $body) {}
    }
    
  2. Create a handler:

    namespace App\MessageHandler;
    
    use App\Message\SendEmailMessage;
    use Symfony\Component\Messenger\Attribute\AsMessageHandler;
    
    #[AsMessageHandler]
    class SendEmailHandler {
        public function __invoke(SendEmailMessage $message) {
            // Logic to send email (e.g., using Symfony Mailer)
        }
    }
    
  3. Dispatch from a controller:

    $this->bus->dispatch(new SendEmailMessage(
        'user@example.com',
        'Welcome!',
        'Thanks for signing up!'
    ));
    

Where to Look First


Implementation Patterns

Core Workflows

1. Message Dispatching

  • Synchronous: Dispatch messages directly in controllers/services.
    $this->bus->dispatch(new YourMessage());
    
  • Asynchronous: Route to a transport (e.g., async).
    # config/packages/messenger.yaml
    routing:
        'App\Message\YourMessage': async
    

2. Handling Messages

  • Annotate Handlers:
    #[AsMessageHandler]
    class YourHandler {
        public function __invoke(YourMessage $message) {
            // Handle logic
        }
    }
    
  • Middleware: Add processing layers (e.g., logging, validation).
    # config/packages/messenger.yaml
    transports:
        async:
            dsn: doctrine://default
            middleware:
                - 'doctrine_transaction' # Built-in for transactions
                - App\Middleware\YourMiddleware
    

3. Consuming Messages

  • Worker Command:
    php bin/console messenger:consume async --time-limit=300
    
  • Scheduled Consumption (e.g., via cron):
    * * * * * php /path/to/your/project/bin/console messenger:consume async --limit=100
    

4. Retry Logic

  • Automatic Retries: Configure in messenger.yaml:
    transports:
        async:
            dsn: doctrine://default
            retry_strategy:
                max_retries: 3
                delay: 1000
                multiplier: 2
    
  • Failed Messages: Check the message_history table or use:
    php bin/console messenger:failed-messages-show
    

Integration Tips

1. Doctrine Transactions

  • Enable transactional handling in messenger.yaml:
    transports:
        async:
            dsn: doctrine://default
            middleware:
                - doctrine_transaction
    
  • Manual Transactions: Use DoctrineTransactionMiddleware in custom middleware.

2. Custom Schema

  • Extend the schema via migrations or events:
    // src/Doctrine/SchemaExtension.php
    namespace App\Doctrine;
    
    use Doctrine\DBAL\Schema\Schema;
    use Symfony\Component\Messenger\Transport\Doctrine\DoctrineTransport;
    
    class SchemaExtension {
        public function __invoke(Schema $schema, DoctrineTransport $transport) {
            $schema->getTable($transport->getTableName())->addColumn('custom_field', 'string');
        }
    }
    
    Register in config/packages/messenger.yaml:
    transports:
        async:
            dsn: doctrine://default
            schema_extension: App\Doctrine\SchemaExtension
    

3. Batching

  • Process messages in batches for efficiency:
    transports:
        async:
            dsn: doctrine://default
            options:
                batch_size: 50
    

4. Prioritization

  • Use multiple transports with routing:
    routing:
        'App\Message\HighPriorityMessage': high_priority
        'App\Message\LowPriorityMessage': low_priority
    transports:
        high_priority:
            dsn: doctrine://default
            options:
                priority: 1
        low_priority:
            dsn: doctrine://default
            options:
                priority: 2
    

5. Testing

  • In-Memory Transport: For unit tests:
    # config/packages/test/messenger.yaml
    transports:
        test:
            dsn: 'doctrine://default'
            options:
                table_name: 'test_messages'
    
  • Mock Handlers: Use MessageBusInterface mocks in PHPUnit:
    $bus = $this->createMock(MessageBusInterface::class);
    $bus->expects($this->once())->method('dispatch');
    

Gotchas and Tips

Pitfalls

  1. Schema Conflicts

    • Issue: Doctrine Messenger creates tables (message, message_history). Conflicts arise if these names clash with existing tables.
    • Fix: Customize table names in the DSN:
      MESSENGER_TRANSPORT_DSN=doctrine://default?table_name=app_messages&history_table_name=app_message_history
      
  2. Transaction Deadlocks

    • Issue: Long-running handlers can cause deadlocks in high-concurrency scenarios.
    • Fix: Use doctrine_transaction middleware sparingly or optimize handler logic. Avoid nested transactions.
  3. PostgreSQL Listener Issues

    • Issue: PostgreSQL transports may fail if UNLISTEN queries are sent unnecessarily (fixed in v8.0.5+).
    • Fix: Update to the latest version or manually manage listeners.
  4. Firebird/Oracle Compatibility

    • Issue: Case-sensitive table names or reserved keywords may cause errors.
    • Fix: Use schema extensions or alias tables:
      transports:
          async:
              dsn: doctrine://default
              options:
                  table_name: "MESSAGES" # Quoted for Firebird
      
  5. Message Size Limits

    • Issue: Large messages (e.g., serialized objects) may exceed database column limits.
    • Fix: Use serialize for complex data or store references to external storage (e.g., S3).

Debugging Tips

  1. Check Failed Messages

    php bin/console messenger:failed-messages-show
    php bin/console messenger:failed-messages-retry [ID]
    
  2. Enable Verbose Logging

    php bin/console messenger:consume async -vv
    

    Or configure in config/packages/monolog.yaml:

    handlers:
        messenger:
            type: stream
            path: "%kernel.logs_dir%/messenger.log"
            level: debug
    
  3. Inspect Database Tables

    -- Check pending messages
    SELECT * FROM message WHERE status = 'envelope';
    
    -- Check history (retries, failures)
    SELECT * FROM message_history ORDER BY created_at DESC;
    
  4. Slow Consumption

    • Cause: Inefficient handlers or database locks.
    • Fix: Profile
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.
codraw/entity-migrator
codraw/doctrine-extra
codraw/aws-tool-kit
codraw/validator
codraw/workflow
codraw/open-api
codraw/cron-job
codraw/process
codraw/log
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony