/**
* Creates a delay queue that will delay for a certain amount of time.
*
* This works by setting message TTL for the delay and pointing
* the dead letter exchange to the original exchange. The result
* is that after the TTL, the message is sent to the dead-letter-exchange,
* which is the original exchange, resulting on it being put back into
* the original queue.
*/
private function createDelayQueue(int
$delay, ?string
$routingKey, bool
$isRetryAttempt): \AMQPQueue
{ $queue =
$this->amqpFactory->
createQueue($this->
channel());
$queue->
setName($this->
getRoutingKeyForDelay($delay,
$routingKey,
$isRetryAttempt));
$queue->
setFlags(\AMQP_DURABLE
);
$queue->
setArguments([ 'x-message-ttl' =>
$delay,
// delete the delay queue 10 seconds after the message expires
// publishing another message redeclares the queue which renews the lease
'x-expires' =>
$delay + 10000,
// message should be broadcast to all consumers during delay, but to only one queue during retry
// empty name is default direct exchange
'x-dead-letter-exchange' =>
$isRetryAttempt ? '' :
$this->exchangeOptions
['name'
],
// after being released from to DLX, make sure the original routing key will be used