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

Skip to content

Commit b107be4

Browse files
committed
feature #59360 [Messenger] Implement KeepaliveReceiverInterface in Redis bridge (HypeMC)
This PR was merged into the 7.3 branch. Discussion ---------- [Messenger] Implement `KeepaliveReceiverInterface` in Redis bridge | Q | A | ------------- | --- | Branch? | 7.3 | Bug fix? | no | New feature? | yes | Deprecations? | no | Issues | - | License | MIT Implements the `KeepaliveReceiverInterface` in the Redis bridge. Commits ------- 769b854 [Messenger] Implement `KeepaliveReceiverInterface` in Redis bridge
2 parents d00ae83 + 769b854 commit b107be4

File tree

8 files changed

+108
-4
lines changed

8 files changed

+108
-4
lines changed

src/Symfony/Component/Messenger/Bridge/Redis/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
7.3
5+
---
6+
7+
* Implement the `KeepaliveReceiverInterface` to enable asynchronously notifying Redis that the job is still being processed, in order to avoid timeouts
8+
49
6.3
510
---
611

src/Symfony/Component/Messenger/Bridge/Redis/Tests/Transport/ConnectionTest.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,45 @@ public function testFromDsnOnUnixSocketWithUser()
485485
);
486486
}
487487

488+
public function testKeepalive()
489+
{
490+
$redis = $this->createRedisMock();
491+
492+
$redis->expects($this->exactly(1))->method('xclaim')
493+
->with('queue', 'symfony', 'consumer', 0, [$id = 'redisid-123'], ['JUSTID'])
494+
->willReturn([]);
495+
496+
$connection = Connection::fromDsn('redis://localhost/queue', [], $redis);
497+
$connection->keepalive($id);
498+
}
499+
500+
public function testKeepaliveWhenARedisExceptionOccurs()
501+
{
502+
$redis = $this->createRedisMock();
503+
504+
$redis->expects($this->exactly(1))->method('xclaim')
505+
->with('queue', 'symfony', 'consumer', 0, [$id = 'redisid-123'], ['JUSTID'])
506+
->willThrowException($exception = new \RedisException('Something went wrong '.time()));
507+
508+
$connection = Connection::fromDsn('redis://localhost/queue', [], $redis);
509+
510+
$this->expectExceptionObject(new TransportException($exception->getMessage(), 0, $exception));
511+
$connection->keepalive($id);
512+
}
513+
514+
public function testKeepaliveWithTooSmallTtl()
515+
{
516+
$redis = $this->createRedisMock();
517+
518+
$redis->expects($this->never())->method('xclaim');
519+
520+
$connection = Connection::fromDsn('redis://localhost/queue?redeliver_timeout=1', [], $redis);
521+
522+
$this->expectException(TransportException::class);
523+
$this->expectExceptionMessage('Redis redeliver_timeout (1000s) cannot be smaller than the keepalive interval (3000s).');
524+
$connection->keepalive('redisid-123', 3000);
525+
}
526+
488527
private function createRedisMock(): \Redis
489528
{
490529
$redis = $this->createMock(\Redis::class);

src/Symfony/Component/Messenger/Bridge/Redis/Tests/Transport/RedisReceiverTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
use Symfony\Component\Messenger\Bridge\Redis\Tests\Fixtures\ExternalMessage;
1717
use Symfony\Component\Messenger\Bridge\Redis\Tests\Fixtures\ExternalMessageSerializer;
1818
use Symfony\Component\Messenger\Bridge\Redis\Transport\Connection;
19+
use Symfony\Component\Messenger\Bridge\Redis\Transport\RedisReceivedStamp;
1920
use Symfony\Component\Messenger\Bridge\Redis\Transport\RedisReceiver;
21+
use Symfony\Component\Messenger\Envelope;
2022
use Symfony\Component\Messenger\Exception\MessageDecodingFailedException;
2123
use Symfony\Component\Messenger\Transport\Serialization\PhpSerializer;
2224
use Symfony\Component\Messenger\Transport\Serialization\Serializer;
@@ -126,4 +128,15 @@ public static function rejectedRedisEnvelopeProvider(): \Generator
126128
],
127129
];
128130
}
131+
132+
public function testKeepalive()
133+
{
134+
$connection = $this->createMock(Connection::class);
135+
$connection->expects($this->once())->method('keepalive')->with('redisid-123');
136+
137+
$receiver = new RedisReceiver($connection, new Serializer(
138+
new SerializerComponent\Serializer([new ObjectNormalizer()], ['json' => new JsonEncoder()])
139+
));
140+
$receiver->keepalive(new Envelope(new DummyMessage('foo'), [new RedisReceivedStamp('redisid-123')]));
141+
}
129142
}

src/Symfony/Component/Messenger/Bridge/Redis/Tests/Transport/RedisTransportTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\Messenger\Bridge\Redis\Tests\Fixtures\DummyMessage;
1616
use Symfony\Component\Messenger\Bridge\Redis\Transport\Connection;
17+
use Symfony\Component\Messenger\Bridge\Redis\Transport\RedisReceivedStamp;
1718
use Symfony\Component\Messenger\Bridge\Redis\Transport\RedisTransport;
1819
use Symfony\Component\Messenger\Envelope;
1920
use Symfony\Component\Messenger\Transport\Serialization\SerializerInterface;
@@ -54,6 +55,18 @@ public function testReceivesMessages()
5455
$this->assertSame($decodedMessage, $envelopes[0]->getMessage());
5556
}
5657

58+
public function testKeepalive()
59+
{
60+
$transport = $this->getTransport(
61+
null,
62+
$connection = $this->createMock(Connection::class),
63+
);
64+
65+
$connection->expects($this->once())->method('keepalive')->with('redisid-123');
66+
67+
$transport->keepalive(new Envelope(new DummyMessage('foo'), [new RedisReceivedStamp('redisid-123')]));
68+
}
69+
5770
private function getTransport(?SerializerInterface $serializer = null, ?Connection $connection = null): RedisTransport
5871
{
5972
$serializer ??= $this->createMock(SerializerInterface::class);

src/Symfony/Component/Messenger/Bridge/Redis/Transport/Connection.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,29 @@ public function setup(): void
624624
$this->autoSetup = false;
625625
}
626626

627+
/**
628+
* @param int|null $seconds the minimum duration the message should be kept alive
629+
*/
630+
public function keepalive(string $id, ?int $seconds = null): void
631+
{
632+
if (null !== $seconds && $this->redeliverTimeout < $seconds) {
633+
throw new TransportException(\sprintf('Redis redeliver_timeout (%ds) cannot be smaller than the keepalive interval (%ds).', $this->redeliverTimeout, $seconds));
634+
}
635+
636+
try {
637+
$this->getRedis()->xclaim(
638+
$this->stream,
639+
$this->group,
640+
$this->consumer,
641+
0,
642+
[$id],
643+
['JUSTID']
644+
);
645+
} catch (\RedisException|\Relay\Exception $e) {
646+
throw new TransportException($e->getMessage(), 0, $e);
647+
}
648+
}
649+
627650
public function cleanup(): void
628651
{
629652
static $unlink = true;

src/Symfony/Component/Messenger/Bridge/Redis/Transport/RedisReceiver.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,16 @@
1515
use Symfony\Component\Messenger\Exception\LogicException;
1616
use Symfony\Component\Messenger\Exception\MessageDecodingFailedException;
1717
use Symfony\Component\Messenger\Exception\TransportException;
18+
use Symfony\Component\Messenger\Transport\Receiver\KeepaliveReceiverInterface;
1819
use Symfony\Component\Messenger\Transport\Receiver\MessageCountAwareInterface;
19-
use Symfony\Component\Messenger\Transport\Receiver\ReceiverInterface;
2020
use Symfony\Component\Messenger\Transport\Serialization\PhpSerializer;
2121
use Symfony\Component\Messenger\Transport\Serialization\SerializerInterface;
2222

2323
/**
2424
* @author Alexander Schranz <[email protected]>
2525
* @author Antoine Bluchet <[email protected]>
2626
*/
27-
class RedisReceiver implements ReceiverInterface, MessageCountAwareInterface
27+
class RedisReceiver implements KeepaliveReceiverInterface, MessageCountAwareInterface
2828
{
2929
private SerializerInterface $serializer;
3030

@@ -89,6 +89,11 @@ public function reject(Envelope $envelope): void
8989
$this->connection->reject($this->findRedisReceivedStamp($envelope)->getId());
9090
}
9191

92+
public function keepalive(Envelope $envelope, ?int $seconds = null): void
93+
{
94+
$this->connection->keepalive($this->findRedisReceivedStamp($envelope)->getId(), $seconds);
95+
}
96+
9297
public function getMessageCount(): int
9398
{
9499
return $this->connection->getMessageCount();

src/Symfony/Component/Messenger/Bridge/Redis/Transport/RedisTransport.php

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

1414
use Symfony\Component\Messenger\Envelope;
15+
use Symfony\Component\Messenger\Transport\Receiver\KeepaliveReceiverInterface;
1516
use Symfony\Component\Messenger\Transport\Receiver\MessageCountAwareInterface;
1617
use Symfony\Component\Messenger\Transport\Serialization\PhpSerializer;
1718
use Symfony\Component\Messenger\Transport\Serialization\SerializerInterface;
@@ -22,7 +23,7 @@
2223
* @author Alexander Schranz <[email protected]>
2324
* @author Antoine Bluchet <[email protected]>
2425
*/
25-
class RedisTransport implements TransportInterface, SetupableTransportInterface, MessageCountAwareInterface
26+
class RedisTransport implements TransportInterface, KeepaliveReceiverInterface, SetupableTransportInterface, MessageCountAwareInterface
2627
{
2728
private SerializerInterface $serializer;
2829
private RedisReceiver $receiver;
@@ -50,6 +51,11 @@ public function reject(Envelope $envelope): void
5051
$this->getReceiver()->reject($envelope);
5152
}
5253

54+
public function keepalive(Envelope $envelope, ?int $seconds = null): void
55+
{
56+
$this->getReceiver()->keepalive($envelope, $seconds);
57+
}
58+
5359
public function send(Envelope $envelope): Envelope
5460
{
5561
return $this->getSender()->send($envelope);

src/Symfony/Component/Messenger/Bridge/Redis/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"require": {
1919
"php": ">=8.2",
2020
"ext-redis": "*",
21-
"symfony/messenger": "^6.4|^7.0"
21+
"symfony/messenger": "^7.2"
2222
},
2323
"require-dev": {
2424
"symfony/property-access": "^6.4|^7.0",

0 commit comments

Comments
 (0)