sroze / messenger-enqueue-transport

Uses Enqueue with Symfony's Messenger component.
MIT License
191 stars 54 forks source link

Add deliveryMode option and functionality for persistent AMQP messages #55

Closed tkocjan closed 5 years ago

tkocjan commented 5 years ago

Add deliveryMode option and functionality for persistent AMQP messages

tkocjan commented 5 years ago

This is a fix for issue #52

I do not see a way to have persistent messages with RabbitMQ. This requires instantiating the following AMQPMessage:

new \PhpAmqpLib\Message\AMQPMessage($body, ['delivery_mode' => 2]);

I cannot see a way to make that happen with existing code.

If I were to implement this, it seems like adding another option to QueueInteropTransport would be the way to do this. Usually, if you are going to persist messages you are going to persist all the messages in a queue and not just selective ones.

I have a fix that allows a deliveryMode param in the DSN. That is then used in the QueueInteropTransport::send() method to do $interopMessage->setDeliveryMode() if the message is an instance of AmqpMessage.

Rather than do it this way, it might be better to add this functionality to AmqpProducer like setPriority() does but that is a lot more work and also requires changes to php-enqueue/enqueue-dev (\Enqueue\AmqpLib\AmqpProducer) and queue-interop/amqp-interop (\Interop\Amqp\AmqpProducer). I did not implement this without first finding out if this way is more appropriate plus not knowing how difficult it will be to get all the changes into three repos.

weaverryan commented 5 years ago

Hi @tkocjan!

Because this option needs to be set directly on the message - e.g. $message->setDeliveryMode(), I think the correct solution ("correct" meaning, consistent with how this library is built) is to set this each time you send the message via the TransportConfiguration metadata:

$bus->dispatch((new Envelope($message))->with(new TransportConfiguration(
    [
        'metadata' => ['deliveryMode' => AmqpMessage::DELIVERY_MODE_PERSISTENT]
    ],
)));

The metadata on the TransportConfiguration are mapped to setter methods on your message object - https://github.com/php-enqueue/messenger-adapter/blob/21e2488461d1ecedc87c2ab579e32518087a289c/QueueInteropTransport.php#L217-L223

I hope that helps! I don't think we will support an option to set this globally, at least I won't.

Cheers!