From b5b486a254be347dd9a1eb86cd38249c2dccd006 Mon Sep 17 00:00:00 2001 From: alschastny <91664363+alschastny@users.noreply.github.com> Date: Wed, 11 Jun 2025 19:28:13 +0300 Subject: [PATCH] add XACK command (#1555) * add XACK command * add XACK to ClientContextInterface * modify CHANGELOG.md --------- Co-authored-by: aleksanders Co-authored-by: Vladyslav Vildanov <117659936+vladvildanov@users.noreply.github.com> --- CHANGELOG.md | 1 + bin/create-command-test | 2 +- src/ClientContextInterface.php | 1 + src/ClientInterface.php | 1 + src/Command/Redis/XACK.php | 34 +++++++++ tests/Predis/Command/Redis/XACK_Test.php | 93 ++++++++++++++++++++++++ 6 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 src/Command/Redis/XACK.php create mode 100644 tests/Predis/Command/Redis/XACK_Test.php diff --git a/CHANGELOG.md b/CHANGELOG.md index e6c57122..66f3acf0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Unreleased ### Added - Add experimental support for vector sets commands (#1550) +- Added support for `XACK` command (#1555) ### Changed - Handle and retry `LOADING` errors from Sentinel replicas (#1536) diff --git a/bin/create-command-test b/bin/create-command-test index 262bd53d..fd12175c 100755 --- a/bin/create-command-test +++ b/bin/create-command-test @@ -15,7 +15,7 @@ // For example, to generate a test case for SET (which is represented by the // Predis\Command\Redis\StringSet class): // -// $ ./bin/generate-command-test --class=StringSet +// $ ./bin/create-command-test --class=StringSet // // Here is a list of optional arguments: // diff --git a/src/ClientContextInterface.php b/src/ClientContextInterface.php index a387daf3..7102d8d7 100644 --- a/src/ClientContextInterface.php +++ b/src/ClientContextInterface.php @@ -284,6 +284,7 @@ use Predis\Command\Redis\VADD; * @method $this tsqueryindex(string ...$filterExpression) * @method $this tsrange(string $key, $fromTimestamp, $toTimestamp, ?RangeArguments $arguments = null) * @method $this tsrevrange(string $key, $fromTimestamp, $toTimestamp, ?RangeArguments $arguments = null) + * @method $this xack(string $key, string $group, string ...$id) * @method $this zadd($key, array $membersAndScoresDictionary) * @method $this zcard($key) * @method $this zcount($key, $min, $max) diff --git a/src/ClientInterface.php b/src/ClientInterface.php index 4d390656..21c32b8e 100644 --- a/src/ClientInterface.php +++ b/src/ClientInterface.php @@ -295,6 +295,7 @@ use Predis\Response\Status; * @method array tsqueryindex(string ...$filterExpression) * @method array tsrange(string $key, $fromTimestamp, $toTimestamp, ?RangeArguments $arguments = null) * @method array tsrevrange(string $key, $fromTimestamp, $toTimestamp, ?RangeArguments $arguments = null) + * @method int xack(string $key, string $group, string ...$id) * @method string xadd(string $key, array $dictionary, string $id = '*', array $options = null) * @method array xautoclaim(string $key, string $group, string $consumer, int $minIdleTime, string $start, ?int $count = null, bool $justId = false) * @method int xdel(string $key, string ...$id) diff --git a/src/Command/Redis/XACK.php b/src/Command/Redis/XACK.php new file mode 100644 index 00000000..545e01fb --- /dev/null +++ b/src/Command/Redis/XACK.php @@ -0,0 +1,34 @@ +applyPrefixForFirstArgument($prefix); + } +} diff --git a/tests/Predis/Command/Redis/XACK_Test.php b/tests/Predis/Command/Redis/XACK_Test.php new file mode 100644 index 00000000..7697188e --- /dev/null +++ b/tests/Predis/Command/Redis/XACK_Test.php @@ -0,0 +1,93 @@ +getCommand(); + $command->setArguments($arguments); + + $this->assertSame($expected, $command->getArguments()); + } + + /** + * @group disconnected + */ + public function testParseResponse(): void + { + $this->assertSame(1, $this->getCommand()->parseResponse(1)); + } + + /** + * @group disconnected + */ + public function testPrefixKeys(): void + { + $arguments = ['stream', 'group', 'id1', 'id2', 'id3']; + $expected = ['prefix:stream', 'group', 'id1', 'id2', 'id3']; + + $command = $this->getCommandWithArgumentsArray($arguments); + $command->prefixKeys('prefix:'); + + $this->assertSame($expected, $command->getArguments()); + } + + /** + * @group connected + * @requiresRedisVersion >= 5.0.0 + */ + public function testAck(): void + { + $redis = $this->getClient(); + + $redis->xadd('stream', ['key0' => 'val0'], '0-1'); + $redis->xadd('stream', ['key1' => 'val1'], '1-1'); + $redis->xadd('stream', ['key2' => 'val2'], '2-1'); + + $redis->xgroup->create('stream', 'group', '0'); + $redis->xreadgroup('group', 'consumer1', 1, null, false, 'stream', '>'); + $this->assertSame(1, $redis->xack('stream', 'group', '0-1')); + $this->assertSame(0, $redis->xack('stream', 'group', '1-1')); + $redis->xreadgroup('group', 'consumer1', 2, null, false, 'stream', '>'); + $this->assertSame(2, $redis->xack('stream', 'group', '1-1', '2-1')); + $this->assertSame(0, $redis->xack('stream', 'group', '1-1', '2-1')); + } +}