Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
772 views
in Technique[技术] by (71.8m points)

symfony - Swiftmailer not sending immediately

I have successfully configure my symfony webapp to sending email using SMTP. But all my sending email are being put into the spool directory.

This should only occurs whem there is an error in the sending. Is that correct?

But if I execute the command swiftmailer:spool:send --env=prod, all my emails are sending correctly.

Why my server are not sending the email immediately? Is that because I fixed an error? Is there any way to fix this?

swiftmailer:

spool:
    type: file
    path: %kernel.root_dir%/spool
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In case somebody is processing emails via message-queue (symfony/messenger), using memory spool is preferred option. However, memory spool is processed only on Kernel::terminate event. This event will never occur on long running console worker.

This kernel event is invoking SymfonyBundleSwiftmailerBundleEventListenerEmailSenderListener::onTerminate() method. You can invoke this method manually by dispatching your own event & subscribing above mentioned method to it.

src/App/Email/Events.php

<?php

namespace AppEmail;

class Events
{
    public const UNSPOOL = 'unspool';
}

config/services.yml

services:    
    AppEmailAmqpHandler:
      tags: [messenger.message_handler]

    SymfonyBundleSwiftmailerBundleEventListenerEmailSenderListener:
        tags:
            - name: kernel.event_listener
              event: !php/const AppEmailEvents::UNSPOOL
              method: onTerminate

your message-queue worker src/App/Email/AmqpHandler.php

<?php

namespace AppEmail;

use SymfonyComponentEventDispatcherEventDispatcherInterface;

class AmqpHandler
{
    /** @var EventDispatcherInterface */
    private $eventDispatcher;

    /** @var Swift_Mailer */
    private $mailer;

    public function __construct(EventDispatcherInterface $eventDispatcher, Swift_Mailer $mailer)
    {
        $this->eventDispatcher = $eventDispatcher;
        $this->mailer = $mailer;
    }

    public function __invoke($emailMessage): void
    {
        //...
        $message = (new Swift_Message($subject))
            ->setFrom($emailMessage->from)
            ->setTo($emailMessage->to)
            ->setBody($emailMessage->body, 'text/html');

        $successfulRecipientsCount = $this->mailer->send($message, $failedRecipients);
        if ($successfulRecipientsCount < 1 || count($failedRecipients) > 0) {
            throw new DeliveryFailureException($message);
        }

        $this->eventDispatcher->dispatch(Events::UNSPOOL);
    }
}

You can read about symfony/messenger here.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...