I'm using the Symfony Messenger component in a Symfony 4.4 application. I'm processing the messages async through RabbitMQ and storing the failed ones in a database through the Doctrine transport.
And this is the messenger config:
framework:
messenger:
failure_transport: failed
buses:
command_bus:
middleware:
- doctrine_ping_connection
transports:
failed: 'doctrine://default?queue_name=failed'
async_priority_high:
dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
retry_strategy:
delay: 2000
max_retries: 5
multiplier: 2
options:
exchange:
name: high
queues:
messages_high: ~
async_priority_low:
dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
retry_strategy:
delay: 3000
max_retries: 3
multiplier: 2
options:
exchange:
name: low
queues:
messages_low: ~
routing:
'App\SampleMessageButHighPriority': async_priority_high
'App\SampleMessageInterface': async_priority_low
'App\OtherMessage': async_priority_low
Here is a sample handler that handler messages imlpementing the SampleMessageInterface
interface.
final class SampleMessageHandler implements MessageHandlerInterface
{
private ProjectRepository $projectRepository;
public function __construct(ProjectRepository $projectRepository)
{
$this->projectRepository = $projectRepository;
}
public function __invoke(SampleMessageInterface $message): void
{
$project = $this->projectRepository->find($message->getProjectId()->toString());
if ($project === null) {
return;
}
$this->someProcessor->__invoke($project);
}
}
Everything is working before facing any message failure. The problem starts showing after failing when trying to retry or show the failed messages. Let's try the php bin/console messenger:failed:show
command:
Result:
In PhpSerializer.php line 64:
Cannot instantiate interface App\SampleMessageInterface
I guess that Symfony needs to unserialize the failed message, previously serialized and stored in the database, but can't do it because it's an interface.
How can I solve this? Is there any way to serialize the failed messages using the class implementation, not the interface?