From 569d7ed715387c02d03a83e079f7316b553bf600 Mon Sep 17 00:00:00 2001 From: Jerrod Carpenter <4128301+JerrodCarpenter@users.noreply.github.com> Date: Fri, 9 Jun 2023 20:26:56 -0500 Subject: [PATCH 1/2] =?UTF-8?q?=E2=9C=A8=20Add=20BLMPOP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/redis/commands/lists.rb | 28 ++++++++++++++++++++++++++++ lib/redis/distributed.rb | 9 ++++++++- test/lint/lists.rb | 13 +++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/lib/redis/commands/lists.rb b/lib/redis/commands/lists.rb index c6383e47d..08a619a21 100644 --- a/lib/redis/commands/lists.rb +++ b/lib/redis/commands/lists.rb @@ -183,6 +183,34 @@ def brpoplpush(source, destination, timeout: 0) send_blocking_command(command, timeout) end + # Pops one or more elements from the first non-empty list key from the list + # of provided key names. If lists are empty, blocks until timeout has passed. + # + # @example Popping a element + # redis.blmpop(1.0, 'list') + # #=> ['list', ['a']] + # @example With count option + # redis.blmpop(1.0, 'list', count: 2) + # #=> ['list', ['a', 'b']] + # + # @params timeout [Float] a float value specifying the maximum number of seconds to block) elapses. + # A timeout of zero can be used to block indefinitely. + # @params key [String, Array] one or more keys with lists + # @params modifier [String] + # - when `"LEFT"` - the elements popped are those from the left of the list + # - when `"RIGHT"` - the elements popped are those from the right of the list + # @params count [Integer] a number of elements to pop + # + # @return [Array>] list of popped elements or nil + def blmpop(timeout, *keys, modifier: "LEFT", count: nil) + raise ArgumentError, "Pick either LEFT or RIGHT" unless modifier == "LEFT" || modifier == "RIGHT" + + args = [:lmpop, keys.size, *keys, modifier] + args << "COUNT" << Integer(count) if count + + send_blocking_command(args, timeout) + end + # Pops one or more elements from the first non-empty list key from the list # of provided key names. # diff --git a/lib/redis/distributed.rb b/lib/redis/distributed.rb index e92d417fa..249ecd3cc 100644 --- a/lib/redis/distributed.rb +++ b/lib/redis/distributed.rb @@ -542,7 +542,14 @@ def ltrim(key, start, stop) node_for(key).ltrim(key, start, stop) end - # Iterate over keys, removing elements from the first non list set found. + # Iterate over keys, blocking and removing elements from the first non empty liist found. + def blmpop(timeout, *keys, modifier: "LEFT", count: nil) + ensure_same_node(:blmpop, keys) do |node| + node.blmpop(timeout, *keys, modifier: modifier, count: count) + end + end + + # Iterate over keys, removing elements from the first non list found. def lmpop(*keys, modifier: "LEFT", count: nil) ensure_same_node(:lmpop, keys) do |node| node.lmpop(*keys, modifier: modifier, count: count) diff --git a/test/lint/lists.rb b/test/lint/lists.rb index fdb37bbe7..1d4b7439e 100644 --- a/test/lint/lists.rb +++ b/test/lint/lists.rb @@ -203,6 +203,19 @@ def test_variadic_rpoplpush_expand assert_equal 'c', redis.rpoplpush('{1}foo', '{1}bar') end + def test_blmpop + target_version('7.0') do + assert_nil r.blmpop( 1.0,'{1}foo') + + r.lpush('{1}foo', %w[a b c d e f g]) + assert_equal ['{1}foo', ['g']], r.blmpop(1.0, '{1}foo') + assert_equal ['{1}foo', ['f', 'e']], r.blmpop(1.0, '{1}foo', count: 2) + + r.lpush('{1}foo2', %w[a b]) + assert_equal ['{1}foo', ['a']], r.blmpop(1.0, '{1}foo', '{1}foo2', modifier: "RIGHT") + end + end + def test_lmpop target_version('7.0') do assert_nil r.lmpop('{1}foo') From 7c931a3c9db9a163c796f8016923e166937cee84 Mon Sep 17 00:00:00 2001 From: Jerrod Carpenter <4128301+JerrodCarpenter@users.noreply.github.com> Date: Fri, 9 Jun 2023 21:11:22 -0500 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=9A=A8=20Fix=20rubocop=20error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/lint/lists.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/lint/lists.rb b/test/lint/lists.rb index 1d4b7439e..ea18254df 100644 --- a/test/lint/lists.rb +++ b/test/lint/lists.rb @@ -205,7 +205,7 @@ def test_variadic_rpoplpush_expand def test_blmpop target_version('7.0') do - assert_nil r.blmpop( 1.0,'{1}foo') + assert_nil r.blmpop(1.0, '{1}foo') r.lpush('{1}foo', %w[a b c d e f g]) assert_equal ['{1}foo', ['g']], r.blmpop(1.0, '{1}foo')