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

Skip to content

Commit e3a2762

Browse files
Add handling for delayed message to redis transport
1 parent ac7938b commit e3a2762

File tree

2 files changed

+33
-9
lines changed

2 files changed

+33
-9
lines changed

src/Symfony/Component/Messenger/Transport/RedisExt/Connection.php

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class Connection
3636

3737
private $connection;
3838
private $stream;
39+
private $queue;
3940
private $group;
4041
private $consumer;
4142
private $autoSetup;
@@ -57,6 +58,7 @@ public function __construct(array $configuration, array $connectionCredentials =
5758
}
5859

5960
$this->stream = $configuration['stream'] ?? self::DEFAULT_OPTIONS['stream'];
61+
$this->queue = $this->stream.'_queue';
6062
$this->group = $configuration['group'] ?? self::DEFAULT_OPTIONS['group'];
6163
$this->consumer = $configuration['consumer'] ?? self::DEFAULT_OPTIONS['consumer'];
6264
$this->autoSetup = $configuration['auto_setup'] ?? self::DEFAULT_OPTIONS['auto_setup'];
@@ -112,6 +114,18 @@ public function get(): ?array
112114
$this->setup();
113115
}
114116

117+
$queuedMessageCount = $this->connection->zcount($this->queue, 0, time());
118+
119+
if ($queuedMessageCount) {
120+
foreach ($this->connection->zpopmin($this->queue, $queuedMessageCount) as $queuedMessage => $time) {
121+
$queuedMessage = json_encode($queuedMessage, true);
122+
// if a futured placed message is actually popped because of a race condition with
123+
// another running message consumer, the message is readded to the queue by add function
124+
// else its just added stream and will be available for all stream consumers
125+
$this->add($queuedMessage['body'], $queuedMessage['headers'], (time() - $time) * 1000);
126+
}
127+
}
128+
115129
$messageId = '>'; // will receive new messages
116130

117131
if ($this->couldHavePendingMessages) {
@@ -182,22 +196,27 @@ public function reject(string $id): void
182196
}
183197
}
184198

185-
public function add(string $body, array $headers): void
199+
/**
200+
* @param int $delay The delay in milliseconds
201+
*/
202+
public function add(string $body, array $headers, int $delay = 0): void
186203
{
187204
if ($this->autoSetup) {
188205
$this->setup();
189206
}
190207

191208
$e = null;
192209
try {
193-
if ($this->maxEntries) {
194-
$added = $this->connection->xadd($this->stream, '*', ['message' => json_encode(
195-
['body' => $body, 'headers' => $headers]
196-
)], $this->maxEntries, true);
210+
$message = json_encode(['body' => $body, 'headers' => $headers]);
211+
212+
if ($delay > 0) { // the delay could be smaller 0 in a queued message
213+
$added = $this->connection->zadd($this->queue, ['NX'], time() + ($delay / 1000), $message);
197214
} else {
198-
$added = $this->connection->xadd($this->stream, '*', ['message' => json_encode(
199-
['body' => $body, 'headers' => $headers]
200-
)]);
215+
if ($this->maxEntries) {
216+
$added = $this->connection->xadd($this->stream, '*', ['message' => $message], $this->maxEntries, true);
217+
} else {
218+
$added = $this->connection->xadd($this->stream, '*', ['message' => $message]);
219+
}
201220
}
202221
} catch (\RedisException $e) {
203222
}

src/Symfony/Component/Messenger/Transport/RedisExt/RedisSender.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Messenger\Transport\RedisExt;
1313

1414
use Symfony\Component\Messenger\Envelope;
15+
use Symfony\Component\Messenger\Stamp\DelayStamp;
1516
use Symfony\Component\Messenger\Transport\Sender\SenderInterface;
1617
use Symfony\Component\Messenger\Transport\Serialization\SerializerInterface;
1718

@@ -37,7 +38,11 @@ public function send(Envelope $envelope): Envelope
3738
{
3839
$encodedMessage = $this->serializer->encode($envelope);
3940

40-
$this->connection->add($encodedMessage['body'], $encodedMessage['headers'] ?? []);
41+
/** @var DelayStamp|null $delayStamp */
42+
$delayStamp = $envelope->last(DelayStamp::class);
43+
$delay = null !== $delayStamp ? $delayStamp->getDelay() : 0;
44+
45+
$this->connection->add($encodedMessage['body'], $encodedMessage['headers'] ?? [], $delay);
4146

4247
return $envelope;
4348
}

0 commit comments

Comments
 (0)