Search code examples
phpsymfonyrabbitmqamqpswiftmailer

Swiftmailer and Symfony Messenger not working with AMQP and rabbitmq within docker


I am desperate with a task.

I bassicly tried everything and can't get to solution.

I am trying to send mail with Swiftmailer asynchronously by using the SymMessenger, AMQP, rabbitmq with docker.

Everything is is installed, but within API platform I always get an error I could not handle.

The idea is to trigger __invoke function on persisting MyEntity entity. I tried with mailcatcher, everything is working so I tried with async examples.

"Attempted to load class "AMQPConnection" from the global namespace.\nDid you forget a "use" statement for "PhpAmqpLib\Connection\AMQPConnection"?",",

I configured parameters starting with docker-compose.yml file

version: '3'

services:
  rabbitmq: # The RabbitMQ container.
      container_name: rabbitmq_container
      build:
        context: .
        dockerfile: scripts/provision/docker/rabbitmq/Dockerfile
      volumes:
        - ./scripts/provision/docker/mysql/data:/var/lib/mysql:cached
      ports: [5672, 15672]

  container_php:
      container_name: container_php
      build: ./scripts/provision/docker/php-fpm/
      expose:
        - 9000
      volumes:
        - .:/var/www/html:cached
      environment:
        - MESSENGER_TRANSPORT_DSN=amqp://guest:guest@rabbitmq:5672/%2f/messages 

My .env file

MESSENGER_TRANSPORT_DSN=amqp://guest:[email protected]:5672/%2f/messages

messenger.yml file

framework:
messenger:
    transports:
        # Uncomment the following line to enable a transport named "amqp"
        amqp_: '%env(MESSENGER_TRANSPORT_DSN)%'

    routing:
        # Route your messages to the transports
      'App\Entity\MyEntity': amqp

In DataPersister class I dispatch:

private function sendWelcomeEmail(MyEntity $myEntity, MessageBus $messageBus)
{
    $messageBus->dispatch($myEntity);
}

And my function in EmailNotificationHandler.

public function __invoke(MyEntity $myEntity) :JsonResponse
{

    $message = (new \Swift_Message(
        'New comment on post'
    ))
        ->setFrom('[email protected]')
        ->setTo('[email protected]')
        ->setBody(
            'There is a new comment on post, check it out!',
            'text/html',
            'UTF-8'
        )
    ;

    $mailer->send($message);

    sleep(5);

    echo 'OK';
  }
}

When I run following command php bin/console messenger:consume amqp in the docker container I get:

I run the container with docker exec -ti rabbitmq_container command.

And then when I execute entity persist in API platform I got the message from above. When data persister is activated, it runs sendWelcomeEmail() which has dispatch method and then __invoke.

I changed SwiftMailer transport but I think that is not an issue.


Solution

  • This issue happens due of swiftmailer flow, it sends messages just on Kernel::terminate event, but this event will not be occurred on worker process.

    To solve this issue, you should:

    1. Dispatch Events::UNSPOOL event - https://stackoverflow.com/a/51730638/9799016
    2. Or use symfony/mailer component (symfony >= 4.3) - https://symfony.com/doc/4.3/mailer.html