'Keep messages when I use the Messenger component with Doctrine
I am using the Messenger component configured with Doctrine to store the messages in a database table.
I see that in the default configuration the table "messenger_messages" is automatically created. In it there is a "delivered_at" field.
I want to keep all the messages that are dispatched but when the messages are consumed the corresponding records are automatically deleted.
When I run the process via php bin/console messenger:consume async -vv
I see that a timestamp is written to the "delivered_at" field but then the entire record is deleted.
Is there a way that the records are not erased and that the date and time of sending the message is recorded?
Solution 1:[1]
It may not express the problem correctly. My application dispatches emails using the Messenger component.
Every email that is dispatched by the application is audited in a file. I can know the amount of mail that the application sends in a period of time.
However, the audited number is not real. The application counts everything that is dispatched. It does not count those that actually reach their destination.
Messenger processes the queue and does not know if the mail is sent by the Mail Server. Just dispatch.
What happen? Emails are obtained from an HTML form. Malformed domains are counted by the application and by Messenger as sent emails.
What I want to obtain is an indicator of how many emails the Mail Server has successfully processed.
I suppose that the solution to my problem is not through the application or the Messenger component, but rather by obtaining some kind of audit from the Mail Server itself.
I tried what Jakumi suggested but the trigger captures all the messages that get to the queue. Even malformed domains like foo@hotmai or [email protected]. The count in this table matches my audit file that records sent emails.
My problem is to count the effectively sent.
Thank you very much for the comments and suggestions.
PS: I apologize for my English. I have used Google's translation services. Wait you understand.
Solution 2:[2]
Giving an answer to the original question and kind of ignoring the following clarifications:
Register a new transport that should hold the sent messages (named 'sent' here):
# config/packages/messenger.yaml
framework:
messenger:
transports:
sent: 'doctrine://default?queue_name=sent'
Then create a new EventSubscriber that forwards the sent messages to the 'sent' transport:
<?php
namespace App\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Messenger\Event\WorkerMessageHandledEvent;
use Symfony\Component\Messenger\Transport\Sender\SenderInterface;
class MessengerMessageConsumedSubscriber implements EventSubscriberInterface
{
private SenderInterface $sentSender;
public function __construct(SenderInterface $sentSender)
{
$this->sentSender = $sentSender;
}
public static function getSubscribedEvents(): array
{
return [
WorkerMessageHandledEvent::class => [
['onWorkerMessageHandled', 10],
]
];
}
public function onWorkerMessageHandled(WorkerMessageHandledEvent $event)
{
$this->sentSender->send($event->getEnvelope());
}
}
Hint the constructor to pick the appropriate sender for the 'sent' transport:
# config/services.yaml
services:
App\EventSubscriber\MessengerMessageConsumedSubscriber:
arguments: ['@messenger.transport.sent']
This way the messages (well, actually copies of your messages) will be kept and messenger_messages.created_at will hold the time of sending.
I agree with yivi though in that you should probably NOT keep the messages in messenger_messages but instead log the data somewhere else...
(Verified on symfony/messenger v5.4.7)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Martin |
Solution 2 | der_abu |