Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Messenger] Negative publisher confirm swallowed #53229

Closed
@Norbomat

Description

@Norbomat

Symfony version(s) affected

<=7

Description

For reliable message publishing, RabbitMQ offers the possibility to enable publisher confirms on a channel. If enabled, the success of processing a message will be confirmed by the broker. If the broker responds with ack, all is fine. In case of receiving nack however, the client is expected to re-publish the message.

Unfortunately, a nack seems to be swallowed by Messenger:
In this line, Messenger waits for the confirm. The waitForConfirm() method then invokes the callback for ack or nack. Both callbacks have been provided here.

As both callbacks just return "false", no further handling of a nack-case is done. There's no way for code which sends a message to know if this has been successful or not.

The expectation would be that at least an exception is thrown in that case. An even better implementation would perform some retries before eventually throwing an exception.

How to reproduce

When a queue is limited and rejects new messages, the publisher is informed by a nack response. This behavior could easily be provoked by creating an overflow scenario.

messenger.yaml

...
    myTransport:
        dsn: amqp://...
        options:
          confirm_timeout: 3 # enable publisher confirms

Assigning a policy in RabbitMQ:
Either assign a policy like explained here. Or use the admin frontend, click "Admin/Policies/Add policy" and enter the values

  • Name: SomeName
  • Definitions:
    • max-lenght=2
    • overflow=reject-publish

Start a SymfonyMessanger consumer

console messenger:consume myTransport

Sending some messages

class MyMessage
{
    public function __construct(readonly string $text){}
}

#[AsMessageHandler]
class MyMessageHandler
{
    public function __construct(private readonly LoggerInterface $logger)
    {
    }

    public function __invoke(MyMessage $message): void
    {
        $this->logger->info("Message received: " . $message->text);
    }
}

for ($i = 0; $i < 100; $i++) {
    $this->messageBus->dispatch(new MyMessage("Message Nr. $i"));
}

Result
-> Only some message are received. The publisher doesn't get any info that it should retry publishing.

Possible Solution

No response

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions