Skip to content
Draft
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* fix(ruby): raise `Valkey::InheritedError` instead of crashing the process when a client created before `fork()` is used in the child ([#255](https://github.com/valkey-io/valkey-glide-ruby/issues/255))
* fix(ruby): `pipelined` and `multi` no longer discard successful replies when a queued command fails at runtime. The block form of `multi` now accepts an `exception:` kwarg (default `true`, matching `pipelined`), so `multi(exception: false) { ... }` returns an Array with `Valkey::CommandError` embedded at the position of any queued command that fails at runtime (e.g. `INCR` on a non-integer), instead of raising and discarding every other command's reply. This matches the server's "no rollback on a runtime error" semantics — other queued commands still commit and their replies stay reachable even though the default is still to raise and discard them. This kwarg only affects the block form; the imperative `multi` (no block) / `#exec` pair has no equivalent control. A genuine queue-time abort (nothing ran) now raises the new `Valkey::ExecAbortError` (a `CommandError` subclass) instead of a plain `CommandError`, so callers can tell the two apart from a mid-EXEC runtime error. Also fixed `incrbyfloat` and `geodist` returning a `String` instead of a `Float` when called inside `multi`/`exec`'s imperative (non-block) form, and a latent bug where a runtime error embedded in that form's `EXEC` reply could be silently coerced to `true` by boolean-typed commands' reconversion ([#260](https://github.com/valkey-io/valkey-glide-ruby/issues/260))
* Ruby: Fix `blpop`, `brpop`, `blmove`, `rpoplpush` and `brpoplpush`, all of which were non-functional. `blpop`/`brpop` called a non-existent `send_blocking_command` helper, `blmove` leaked the command name into argv, and `rpoplpush`/`brpoplpush` dispatched `RequestType::RPOPLPUSH`/`BRPOPLPUSH`, for which glide-core has no command mapping. Since Valkey defines `RPOPLPUSH src dst` as exactly `LMOVE src dst RIGHT LEFT` (and `BRPOPLPUSH src dst timeout` as `BLMOVE src dst RIGHT LEFT timeout`), `rpoplpush`/`brpoplpush` are now fixed-argument facades over `lmove`/`blmove`. Both remain deprecated as of Redis 6.2; prefer `lmove`/`blmove` in new code. The unusable `RequestType::RPOPLPUSH`/`BRPOPLPUSH` constants were removed.
* fix(ruby): correct the documented cluster return types for `bgsave`, `bgrewriteaof`, `lastsave`, `lolwut`, `function_dump`, `function_list`, `randomkey` and `function_stats`. The first six can return a per-node `Hash` keyed by `"host:port"` but documented only a scalar — and `bgsave`/`bgrewriteaof` do so even with no `route:`, since they default to all primaries — while `randomkey` documented a per-node `Hash` it never returns (glide-core collapses it to a single key, or `nil` when every shard is empty) and `function_stats` documented a `"host:port"`-keyed `Hash` unconditionally, though a single-node route returns that node's stats unkeyed ([#312](https://github.com/valkey-io/valkey-glide-ruby/pull/312))

### Changes

Expand Down
16 changes: 10 additions & 6 deletions lib/valkey/commands/function_commands.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ def function_delete(library_name, route: nil)
# valkey.function_dump
# # => <binary string>
#
# @param route [Valkey::Route, nil] cluster routing. When routed, may return a Hash of node => value.
# @return [String] the serialized payload
# @param route [Valkey::Route, nil] cluster routing. A multi-node route returns a `Hash` of
# `"host:port" => String`.
# @return [String, Hash{String => String}] the serialized payload
#
# @see https://valkey.io/commands/function-dump/
def function_dump(route: nil)
Expand Down Expand Up @@ -94,8 +95,9 @@ def function_kill(route: nil)
#
# @param [String] library_name filter by library name pattern
# @param [Boolean] with_code include the library code in the response
# @param route [Valkey::Route, nil] cluster routing. When routed, may return a Hash of node => value.
# @return [Array<Hash>] array of library information
# @param route [Valkey::Route, nil] cluster routing. Default is a single random node.
# A multi-node route returns a `Hash` of `"host:port" => Array<Hash>`.
# @return [Array<Hash>, Hash{String => Array<Hash>}] array of library information
#
# @see https://valkey.io/commands/function-list/
def function_list(library_name: nil, with_code: false, route: nil)
Expand Down Expand Up @@ -171,8 +173,10 @@ def function_restore(serialized_value, policy: nil, route: nil)
# valkey.function_stats
# # => {"127.0.0.1:6379" => {"running_script" => nil, "engines" => {...}}}
#
# @param route [Valkey::Route, nil] cluster routing. When routed, may return a Hash of node => value.
# @return [Hash{String => Hash}] a Hash keyed by `"host:port"`.
# @param route [Valkey::Route, nil] cluster routing. On cluster the default is all nodes, so the
# reply is keyed by `"host:port"` even with no route. A single-node route returns that node's
# stats directly, without the `"host:port"` key.
# @return [Hash{String => Hash}, Hash] a Hash keyed by `"host:port"`, or one node's stats.
#
# @see https://valkey.io/commands/function-stats/
def function_stats(route: nil)
Expand Down
3 changes: 2 additions & 1 deletion lib/valkey/commands/generic_commands.rb
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,8 @@ def object(subcommand, *args)

# Return a random key from the keyspace.
#
# @param route [Valkey::Route, nil] cluster routing. When routed, may return a Hash of node => value.
# @param route [Valkey::Route, nil] cluster routing. Never returns a per-node Hash: glide-core
# collapses multi-node replies to the first non-empty key, or `nil` if every shard is empty.
# @return [String, nil]
def randomkey(route: nil)
send_command(RequestType::RANDOM_KEY, [], route: route)
Expand Down
20 changes: 12 additions & 8 deletions lib/valkey/commands/server_commands.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,18 @@ module Commands
module ServerCommands
# Asynchronously rewrite the append-only file.
#
# @param route [Valkey::Route, nil] cluster routing. When routed, may return a Hash of node => value.
# @return [String]
# @param route [Valkey::Route, nil] cluster routing. On cluster the default is all primaries,
# so the reply is a per-node Hash even with no route. A single-node route returns a String.
# @return [String, Hash{String => String}]
def bgrewriteaof(route: nil)
send_command(RequestType::BG_REWRITE_AOF, [], route: route)
end

# Asynchronously save the dataset to disk.
#
# @param route [Valkey::Route, nil] cluster routing. When routed, may return a Hash of node => value.
# @return [String]
# @param route [Valkey::Route, nil] cluster routing. On cluster the default is all primaries,
# so the reply is a per-node Hash even with no route. A single-node route returns a String.
# @return [String, Hash{String => String}]
def bgsave(route: nil)
send_command(RequestType::BG_SAVE, [], route: route)
end
Expand Down Expand Up @@ -173,8 +175,9 @@ def parse_info_reply(reply, cmd)

# Get the UNIX time stamp of the last successful save to disk.
#
# @param route [Valkey::Route, nil] cluster routing. When routed, may return a Hash of node => value.
# @return [Integer]
# @param route [Valkey::Route, nil] cluster routing. Default is a single random node.
# A multi-node route returns a `Hash` of `"host:port" => Integer`.
# @return [Integer, Hash{String => Integer}]
def lastsave(route: nil)
send_command(RequestType::LAST_SAVE, [], route: route)
end
Expand Down Expand Up @@ -532,8 +535,9 @@ def failover(to: nil, force: false, abort: false, timeout: nil)
# Display some computer art and the Valkey version.
#
# @param version [Integer, nil] optional version number for different art
# @param route [Valkey::Route, nil] cluster routing. When routed, may return a Hash of node => value.
# @return [String] ASCII art and version information
# @param route [Valkey::Route, nil] cluster routing. Default is a single random node.
# A multi-node route returns a `Hash` of `"host:port" => String`.
# @return [String, Hash{String => String}] ASCII art and version information
#
# @example
# valkey.lolwut
Expand Down
Loading