Skip to content

Commit f174e80

Browse files
committed
delay strategy
1 parent 918bff6 commit f174e80

File tree

3 files changed

+107
-0
lines changed

3 files changed

+107
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
namespace Enqueue\Client\Amqp;
4+
5+
use Interop\Amqp\AmqpContext;
6+
use Interop\Amqp\AmqpDestination;
7+
use Interop\Amqp\AmqpMessage;
8+
use Interop\Amqp\AmqpQueue;
9+
use Interop\Amqp\AmqpTopic;
10+
use Interop\Amqp\Impl\AmqpBind;
11+
12+
class DelayPluginDelayStrategy implements DelayStrategy
13+
{
14+
public function delayMessage(AmqpContext $context, AmqpDestination $dest, AmqpMessage $message)
15+
{
16+
$delaySec = 1235; // $message->getDelay();
17+
18+
if ($dest instanceof AmqpTopic) {
19+
$delayTopic = $context->createTopic($dest->getTopicName().'.x.delayed');
20+
$delayTopic->setType('x-delayed-message');
21+
$delayTopic->addFlag(AmqpTopic::FLAG_DURABLE);
22+
$delayTopic->setArgument('x-delayed-type', AmqpTopic::TYPE_DIRECT);
23+
24+
$context->declareTopic($delayTopic);
25+
$context->bind(new AmqpBind($dest, $delayTopic));
26+
} elseif ($dest instanceof AmqpQueue) {
27+
$delayTopic = $context->createTopic($dest->getQueueName().'.delayed');
28+
$delayTopic->setType('x-delayed-message');
29+
$delayTopic->addFlag(AmqpTopic::FLAG_DURABLE);
30+
$delayTopic->setArgument('x-delayed-type', AmqpTopic::TYPE_DIRECT);
31+
32+
$context->declareTopic($delayTopic);
33+
$context->bind(new AmqpBind($delayTopic, $dest, $dest->getQueueName()));
34+
} else {
35+
throw new \LogicException();
36+
}
37+
38+
$delayMessage = $context->createMessage($message->getBody(), $message->getProperties(), $message->getHeaders());
39+
$delayMessage->setProperty('x-delay', (string) ($delaySec * 1000));
40+
41+
$context->createProducer()->send($delayTopic, $delayMessage);
42+
}
43+
}
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace Enqueue\Client\Amqp;
4+
5+
use Interop\Amqp\AmqpContext;
6+
use Interop\Amqp\AmqpDestination;
7+
use Interop\Amqp\AmqpMessage;
8+
9+
interface DelayStrategy
10+
{
11+
/**
12+
* @param AmqpContext $context
13+
* @param AmqpDestination $dest
14+
* @param AmqpMessage $message
15+
*/
16+
public function delayMessage(AmqpContext $context, AmqpDestination $dest, AmqpMessage $message);
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
namespace Enqueue\Client\Amqp;
4+
5+
use Interop\Amqp\AmqpContext;
6+
use Interop\Amqp\AmqpDestination;
7+
use Interop\Amqp\AmqpMessage;
8+
use Interop\Amqp\AmqpQueue;
9+
use Interop\Amqp\AmqpTopic;
10+
11+
class DlxDelayStrategy implements DelayStrategy
12+
{
13+
/**
14+
* {@inheritdoc}
15+
*/
16+
public function delayMessage(AmqpContext $context, AmqpDestination $dest, AmqpMessage $message)
17+
{
18+
$delaySec = 1235; // $message->getDelay();
19+
20+
if ($dest instanceof AmqpTopic) {
21+
$delayQueue = $context->createQueue($dest->getTopicName().'.'.$delaySec.'.x.delayed');
22+
$delayQueue->addFlag(AmqpTopic::FLAG_DURABLE);
23+
$delayQueue->setArgument('x-dead-letter-exchange', $dest->getTopicName());
24+
} elseif ($dest instanceof AmqpQueue) {
25+
$delayQueue = $context->createQueue($dest->getQueueName().'.'.$delaySec.'.delayed');
26+
$delayQueue->addFlag(AmqpTopic::FLAG_DURABLE);
27+
$delayQueue->setArgument('x-dead-letter-exchange', '');
28+
$delayQueue->setArgument('x-dead-letter-routing-key', $dest->getQueueName());
29+
} else {
30+
throw new \LogicException();
31+
}
32+
33+
$context->declareQueue($delayQueue);
34+
35+
$properties = $message->getProperties();
36+
37+
// The x-death header must be removed because of the bug in RabbitMQ.
38+
// It was reported that the bug is fixed since 3.5.4 but I tried with 3.6.1 and the bug still there.
39+
// https://github.com/rabbitmq/rabbitmq-server/issues/216
40+
unset($properties['x-death']);
41+
42+
$delayMessage = $context->createMessage($message->getBody(), $properties, $message->getHeaders());
43+
$delayMessage->setExpiration((string) ($delaySec * 1000));
44+
45+
$context->createProducer()->send($delayQueue, $delayMessage);
46+
}
47+
}

0 commit comments

Comments
 (0)