Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions lib/valkey/commands/generic_commands.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ module Commands
module GenericCommands
# Scan the keyspace
#
# @note Standalone mode only. glide-core has no defined default route for
# SCAN in cluster mode, so each call may land on a different node with
# no cursor continuity between them — results are undefined (missed or
# duplicated keys) rather than merely partial.
# @note Standalone mode only. In cluster mode this returns `["0", []]`
# (a finished cursor and no keys) rather than iterating a single shard
# with an undefined route. A cluster-aware scan API is tracked in
# TODO: https://github.com/valkey-io/valkey-glide-ruby/issues/133
#
# @example Retrieve the first batch of keys
# valkey.scan(0)
Expand All @@ -33,13 +33,16 @@ module GenericCommands
# @return [String, Array<String>] the next cursor and all found keys
#
def scan(cursor, **options)
return ["0", []] if @cluster_mode

_scan(RequestType::SCAN, cursor, [], **options)
end

# Scan the keyspace
#
# @note Standalone mode only. Built on {#scan}, which has undefined
# routing behavior in cluster mode (see its note).
# @note Standalone mode only. In cluster mode this yields nothing and
# returns immediately, matching {#scan}'s cluster behavior. See
# TODO: https://github.com/valkey-io/valkey-glide-ruby/issues/133
#
# @example Retrieve all of the keys (with possible duplicates)
# valkey.scan_each.to_a
Expand All @@ -62,6 +65,7 @@ def scan(cursor, **options)
#
def scan_each(**options, &block)
return to_enum(:scan_each, **options) unless block_given?
return if @cluster_mode

cursor = 0
loop do
Expand Down
20 changes: 14 additions & 6 deletions test/lint/generic_commands.rb
Original file line number Diff line number Diff line change
Expand Up @@ -349,12 +349,15 @@ def test_renamenx
end

def test_scan
# The set_some_keys method sets both tagged and untagged keys
# In cluster mode, scan only sees keys on the node being scanned
skip("SCAN with match pattern may not see all keys in cluster mode") if cluster_mode?

set_some_keys

# scan is standalone only.
# For cluster support, see https://github.com/valkey-io/valkey-glide-ruby/issues/133
if cluster_mode?
assert_equal ["0", []], valkey.scan(0, match: '{key}*')
return
end

cursor = 0
all_keys = []
loop do
Expand All @@ -367,10 +370,15 @@ def test_scan
end

def test_scan_each
skip("SCAN with match pattern may not see all keys in cluster mode") if cluster_mode?

set_some_keys

# scan_each is standalone only.
# For cluster support, see https://github.com/valkey-io/valkey-glide-ruby/issues/133
if cluster_mode?
assert_empty valkey.scan_each(match: '{key}*').to_a
return
end

all_keys = valkey.scan_each(match: '{key}*').to_a

assert_equal 2, all_keys.uniq.size
Expand Down
Loading