valkey-glide-rb 0.9.5 → 1.0.0.pre.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -10
  3. data/AGENTS.md +15 -31
  4. data/CHANGELOG.md +0 -9
  5. data/CLAUDE.md +1 -1
  6. data/CONTRIBUTING.md +3 -3
  7. data/DEVELOPER.md +20 -17
  8. data/README.md +40 -40
  9. data/Rakefile +1 -4
  10. data/lib/valkey/commands/cluster_commands.rb +18 -12
  11. data/lib/valkey/commands/connection_commands.rb +68 -28
  12. data/lib/valkey/commands/function_commands.rb +15 -13
  13. data/lib/valkey/commands/generic_commands.rb +8 -17
  14. data/lib/valkey/commands/hash_commands.rb +13 -13
  15. data/lib/valkey/commands/list_commands.rb +77 -109
  16. data/lib/valkey/commands/pubsub_commands.rb +2 -4
  17. data/lib/valkey/commands/scripting_commands.rb +49 -127
  18. data/lib/valkey/commands/server_commands.rb +49 -42
  19. data/lib/valkey/commands/set_commands.rb +4 -4
  20. data/lib/valkey/commands/stream_commands.rb +10 -20
  21. data/lib/valkey/commands/string_commands.rb +61 -28
  22. data/lib/valkey/commands/transaction_commands.rb +10 -64
  23. data/lib/valkey/commands/vector_search_commands.rb +1 -1
  24. data/lib/valkey/commands.rb +4 -2
  25. data/lib/valkey/native/aarch64-apple-darwin/libglide_ffi.dylib +0 -0
  26. data/lib/valkey/native/aarch64-unknown-linux-gnu/libglide_ffi.so +0 -0
  27. data/lib/valkey/native/aarch64-unknown-linux-musl/libglide_ffi.so +0 -0
  28. data/lib/valkey/native/x86_64-unknown-linux-gnu/libglide_ffi.so +0 -0
  29. data/lib/valkey/native/x86_64-unknown-linux-musl/libglide_ffi.so +0 -0
  30. data/lib/valkey/opentelemetry.rb +5 -26
  31. data/lib/valkey/pipeline.rb +2 -171
  32. data/lib/valkey/pubsub_callback.rb +0 -13
  33. data/lib/valkey/read_from.rb +8 -1
  34. data/lib/valkey/request_type.rb +2 -0
  35. data/lib/valkey/route.rb +0 -2
  36. data/lib/valkey/utils.rb +76 -71
  37. data/lib/valkey/version.rb +1 -1
  38. data/lib/valkey.rb +104 -163
  39. metadata +4 -5
  40. data/lib/valkey/future.rb +0 -85
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 81ff9bce97a9bd2e790689d82f4f7a3e2b43217e06691d147c5c7dd7005e9362
4
- data.tar.gz: e9e2a2d02a7ad14fa6e78da1cf259537f671868c8cad1486df3bde1e69aea2fe
3
+ metadata.gz: 31e06a1cd3c0ecb6cd124d2d65c232cd080f5d5b9c3beaec4edac11ca8c9ddd4
4
+ data.tar.gz: a72a457f3533a2ee91c3b4d3a33633d4a5b19f73482c71fd6405c7c5229b3a1e
5
5
  SHA512:
6
- metadata.gz: 3cabf9e3463367cb10bdfe4962ab18ea47e14d41f89e7c94569f783582207d99533b602ebf8b680b0aba14039851ebe415854eebb36687d0c814ce8a21600db1
7
- data.tar.gz: 99606f6199249c6c370e7b8599bc4b4983069498d2725b7e1aabbe82ea039625f4c2c470859b5d3d0b24fbc648c24d660dba066fa19320c4d3b711700aedabd2
6
+ metadata.gz: 3f3384dfc9de4a87b7efd6464e2b724534339e2b56f748f4399283a290303ab54361f057c8069c19bb38ce29f621aa0056ac2f96975f81717c023bdf3a2c75fe
7
+ data.tar.gz: bb8378c230ffde26c7abe0f3755d002c5f2bd67e345b2e380036fd07b5b9731b61c7c61bf36d2302a559d33f769daaa86386986de0f69285839a5638235a7f75
data/.rubocop.yml CHANGED
@@ -1,7 +1,7 @@
1
1
  inherit_from: .rubocop_todo.yml
2
2
 
3
3
  AllCops:
4
- TargetRubyVersion: 3.0
4
+ TargetRubyVersion: 2.6
5
5
  NewCops: enable
6
6
  Exclude:
7
7
  - 'vendor/**/*'
@@ -68,12 +68,3 @@ Metrics/ModuleLength:
68
68
  - 'lib/valkey/bindings.rb'
69
69
  - 'lib/valkey/opentelemetry.rb'
70
70
  - 'test/**/*.rb'
71
-
72
- # This gem is backported to run on Ruby 2.7 (see required_ruby_version in
73
- # valkey.gemspec), while TargetRubyVersion stays at 3.0 for general style.
74
- # The two cops below assume the gem's minimum Ruby is 3.0, which isn't true here.
75
- Style/HashExcept:
76
- Enabled: false # Hash#except is Ruby 3.0+; we use Hash#reject to stay 2.7-compatible
77
-
78
- Gemspec/RequiredRubyVersion:
79
- Enabled: false # required_ruby_version (>= 2.6) is intentionally below TargetRubyVersion
data/AGENTS.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # AGENTS: Ruby Client Context for Agentic Tools
2
2
 
3
- This file provides AI agents and developers with the minimum but sufficient context to work productively with the Valkey GLIDE Ruby client (`valkey-glide-rb`). It covers build commands, testing, contribution requirements, and essential guardrails specific to the Ruby implementation.
3
+ This file provides AI agents and developers with the minimum but sufficient context to work productively with the Valkey GLIDE Ruby client (`valkey-rb`). It covers build commands, testing, contribution requirements, and essential guardrails specific to the Ruby implementation.
4
4
 
5
5
  ## Repository Overview
6
6
 
7
- This is the **Ruby client** for Valkey GLIDE, published as the `valkey-glide-rb` gem. It provides a synchronous API on top of the Rust GLIDE core via FFI.
7
+ This is the **Ruby client** for Valkey GLIDE, published as the `valkey-rb` gem. It provides a synchronous, redis-rb-compatible API on top of the Rust GLIDE core via FFI.
8
8
 
9
9
  **Primary Languages:** Ruby, Rust (FFI native library, built separately from [valkey-glide](https://github.com/valkey-io/valkey-glide))
10
10
 
@@ -20,7 +20,7 @@ This is the **Ruby client** for Valkey GLIDE, published as the `valkey-glide-rb`
20
20
  - `lib/valkey/opentelemetry.rb` — Native OTel configuration
21
21
  - `test/valkey/` — Standalone integration tests
22
22
  - `test/cluster/` — Cluster integration tests
23
- - `test/lint/` — Lint suites
23
+ - `test/lint/` — redis-rb compatibility lint suites
24
24
 
25
25
  ## Architecture Quick Facts
26
26
 
@@ -28,7 +28,7 @@ This is the **Ruby client** for Valkey GLIDE, published as the `valkey-glide-rb`
28
28
 
29
29
  **Client Types:** `Valkey` — standalone or cluster (`cluster_mode: true`)
30
30
 
31
- **API Style:** Synchronous, blocking calls.
31
+ **API Style:** Synchronous, blocking calls (redis-rb style)
32
32
 
33
33
  **Communication:** Direct FFI (`Bindings.command`, `Bindings.batch`)
34
34
 
@@ -38,9 +38,9 @@ This is the **Ruby client** for Valkey GLIDE, published as the `valkey-glide-rb`
38
38
  - Alpine Linux 3.18+ (x86_64, aarch64) — musl libc
39
39
  - macOS: 13.7+ (x86_64), 14.7+ (aarch64)
40
40
 
41
- **Ruby Versions:** 3.0, 3.1, 3.2, 3.3, 3.4, JRuby (CI matrix)
41
+ **Ruby Versions:** 2.6, 2.7, 3.0, 3.1, 3.2, 3.3, 3.4, JRuby (CI matrix)
42
42
 
43
- **Gem name:** `valkey-glide-rb` on RubyGems
43
+ **Gem name:** `valkey-rb` on RubyGems
44
44
 
45
45
  ## Build and Test Rules (Agents)
46
46
 
@@ -83,26 +83,10 @@ RUBYOPT="-I$(pwd)/lib" ruby -r valkey -e 'p Valkey.new.ping'
83
83
  | Suite | Server requirement |
84
84
  |-------|-------------------|
85
85
  | `test:standalone` | Standalone Valkey/Redis on `localhost:6379` (DB 15) |
86
- | `test:cluster` | 6-node cluster on `127.0.0.1:7000`–`7005` (auto-started by the suite) |
87
- | SSL tests | TLS Valkey on port `6380` + `export TLS_CERT_DIR=...` (or `SKIP_TLS_TESTS=true`) |
86
+ | `test:cluster` | 6-node cluster on `127.0.0.1:7000`–`7005` |
87
+ | SSL tests | TLS Valkey on port `6380` + certs in `test/fixtures/ssl/` |
88
88
  | Module tests | JSON, Bloom, Search modules loaded (see CI workflow) |
89
89
 
90
- Start test servers with `cluster_manager.py` (matching CI). The cluster is
91
- auto-started by the suite; standalone and TLS are started manually:
92
-
93
- ```bash
94
- # Standalone on :6379
95
- python3 valkey-glide/utils/cluster_manager.py start -r 0 -p 6379 --prefix standalone
96
-
97
- # TLS on :6380 (generates certs in valkey-glide/utils/tls_crts/)
98
- python3 valkey-glide/utils/cluster_manager.py --tls start -r 0 -p 6380 --prefix tls-standalone
99
- export TLS_CERT_DIR=$(pwd)/valkey-glide/utils/tls_crts # required for TLS tests
100
-
101
- # Stop when done
102
- python3 valkey-glide/utils/cluster_manager.py stop --prefix standalone
103
- python3 valkey-glide/utils/cluster_manager.py --tls stop --prefix tls-standalone
104
- ```
105
-
106
90
  ### Rebuild Native FFI (when changing glide-core)
107
91
 
108
92
  ```bash
@@ -157,15 +141,15 @@ cargo fmt --manifest-path ./Cargo.toml --all
157
141
  - `*.gem` — built gem packages
158
142
  - `coverage/` — coverage reports
159
143
  - `tmp/`, `test/tmp/` — temporary test artifacts
160
- - SSL certs — never commit them; TLS tests read certs from `TLS_CERT_DIR` (generated by `cluster_manager.py --tls`)
144
+ - Regenerated SSL certs unless intentionally updated (`test/fixtures/ssl/*.pem` may be committed for CI)
161
145
  - Wrong-platform `libglide_ffi` binaries (build per OS/arch)
162
146
 
163
147
  ### Ruby-Specific Rules
164
148
 
165
- - **Ruby 3.0+ Required:** Minimum per `valkey.gemspec`
149
+ - **Ruby 2.6+ Required:** Minimum per `valkey.gemspec`
166
150
  - **FFI dependency:** `ffi ~> 1.17.0` — do not break ABI without rebuilding native lib
167
151
  - **Synchronous only:** No async client in this repo; do not add EventMachine/async patterns without design review
168
- - **redis-rb conventions:** Prefer matching redis-rb method signatures and return types when implementing commands for familiarity.
152
+ - **redis-rb compatibility:** Prefer matching redis-rb method signatures and return types when implementing commands
169
153
  - **Command args:** All FFI args are strings; convert types in Ruby before `send_command`
170
154
  - **Pipeline transactions:** `MULTI`/`EXEC`/`DISCARD` in `pipelined` use sequential fallback — do not remove without fixing FFI batch stability
171
155
  - **OpenTelemetry:** Init once per process via `Valkey::OpenTelemetry.init`; spans created in FFI layer
@@ -201,7 +185,7 @@ valkey-glide-ruby/
201
185
  ├── test/lint/ # shared lint
202
186
  ├── valkey.gemspec
203
187
  ├── Rakefile
204
- └── .github/workflows/ci.yml
188
+ └── .github/workflows/CI.yml
205
189
  ```
206
190
 
207
191
  ## Quality Gates (Agent Checklist)
@@ -219,11 +203,11 @@ valkey-glide-ruby/
219
203
 
220
204
  ## Quick Facts for Reasoners
221
205
 
222
- **Package:** `valkey-glide-rb` on RubyGems
223
- **API Style:** Synchronous.
206
+ **Package:** `valkey-rb` on RubyGems
207
+ **API Style:** Synchronous, redis-rb-compatible
224
208
  **Client:** `Valkey.new` — standalone or `cluster_mode: true`
225
209
  **Key Features:** Pipelining, OpenTelemetry (native), statistics, TLS, URL parsing, cluster routing
226
- **Testing:** Minitest + rake tasks; lint suites.
210
+ **Testing:** Minitest + rake tasks; lint suites for redis-rb parity
227
211
  **Core repo:** [valkey-glide](https://github.com/valkey-io/valkey-glide) (`ffi/`, `glide-core/`)
228
212
  **This repo:** [valkey-glide-ruby](https://github.com/valkey-io/valkey-glide-ruby)
229
213
 
data/CHANGELOG.md CHANGED
@@ -2,16 +2,7 @@
2
2
 
3
3
  ## Pending
4
4
 
5
- ### Fixes
6
-
7
- * 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.
8
-
9
5
  ### Changes
10
6
 
11
- * Ruby: fixed cd workflow to correctly build the ffi with **glibc 2.17** ([#223](https://github.com/valkey-io/valkey-glide-ruby/issues/223))
12
- * Ruby: scripting commands now dispatch real `EVAL` / `EVALSHA` / `SCRIPT LOAD` to the server instead of a client-side script container ([#213](https://github.com/valkey-io/valkey-glide-ruby/issues/213)). Three behavior changes:
13
- * `eval` / `evalsha` (and the `_ro` variants) now accept the standard integer key-count form used by `valkey-cli` and the Valkey docs — `eval(script, 1, "mykey", "myarg")`. It previously made the count `KEYS[1]`, shifted the real key into `ARGV[1]`, and dropped the remaining arguments without raising.
14
- * `script_load` now really sends `SCRIPT LOAD`, so the returned SHA1 is known to the server and usable by `evalsha` from any other client or process. `script_exists` previously reported `false` for a just-loaded script.
15
- * `evalsha` on a flushed or never-loaded SHA now raises `Valkey::CommandError` (NOSCRIPT) instead of silently re-uploading the script and succeeding, so `script_flush` is no longer quietly undone. Callers relying on the old auto-reload must load the script again after a flush, or use `eval`.
16
7
  * Ruby: Add Alpine Linux (musl libc) support for x86_64 and aarch64 — runtime detection of musl libc, CI/CD pipeline for native builds, and prebuilt `libglide_ffi.so` for musl targets ([#143](https://github.com/valkey-io/valkey-glide-ruby/pull/143))
17
8
  * Ruby: Add distributed tracing support — `Valkey::OpenTelemetry.set_parent_span_context_provider` (and `init(parent_span_context_provider:)`) let an app propagate its current W3C trace context into command/pipeline spans, so they become children of the app's trace instead of independent root spans, matching the Node.js client's `parentSpanContextProvider` behavior.
data/CLAUDE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # CLAUDE.md
2
2
 
3
- Valkey GLIDE Ruby (`valkey-glide-rb`) is the official Ruby binding for Valkey and Redis OSS. It uses the shared Rust **glide-core** driver via the **glide-ffi** C library. This repository is separate from the [valkey-glide](https://github.com/valkey-io/valkey-glide) mono-repo (Python, Java, Node, Go).
3
+ Valkey GLIDE Ruby (`valkey-rb`) is the official Ruby binding for Valkey and Redis OSS. It uses the shared Rust **glide-core** driver via the **glide-ffi** C library, with a redis-rb-compatible Ruby API. This repository is separate from the [valkey-glide](https://github.com/valkey-io/valkey-glide) mono-repo (Python, Java, Node, Go).
4
4
 
5
5
  ## Hard Constraints (non-negotiable)
6
6
 
data/CONTRIBUTING.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Contributing Guidelines
2
2
 
3
- Thank you for your interest in contributing to Valkey GLIDE for Ruby (`valkey-glide-rb`). Whether it's a bug report, new feature, correction, or documentation, we value feedback from the community.
3
+ Thank you for your interest in contributing to Valkey GLIDE for Ruby (`valkey-rb`). Whether it's a bug report, new feature, correction, or documentation, we value feedback from the community.
4
4
 
5
5
  Please read this document before submitting issues or pull requests.
6
6
 
@@ -11,7 +11,7 @@ Use the [GitHub issue tracker](https://github.com/valkey-io/valkey-glide-ruby/is
11
11
  Before creating a new issue:
12
12
 
13
13
  1. Search [existing issues](https://github.com/valkey-io/valkey-glide-ruby/issues) to avoid duplicates.
14
- 2. Include Ruby version, OS/architecture, `valkey-glide-rb` version, and Valkey/Redis server version.
14
+ 2. Include Ruby version, OS/architecture, `valkey-rb` version, and Valkey/Redis server version.
15
15
  3. For connection problems, note standalone vs cluster and whether TLS is enabled.
16
16
  4. Provide a minimal reproduction script when possible.
17
17
 
@@ -39,7 +39,7 @@ For issues that affect the shared Rust core or other language clients, consider
39
39
  ```
40
40
  Configure automatic signoff: `git config --global format.signOff true`
41
41
 
42
- 5. Open a PR and respond to CI feedback (RuboCop + test matrix in `.github/workflows/ci.yml`).
42
+ 5. Open a PR and respond to CI feedback (RuboCop + test matrix in `.github/workflows/CI.yml`).
43
43
 
44
44
  GitHub guides: [fork a repo](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo), [create a pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request).
45
45
 
data/DEVELOPER.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Developer Guide
2
2
 
3
- This document describes how to set up your development environment to build and test the Valkey GLIDE Ruby client (`valkey-glide-rb`).
3
+ This document describes how to set up your development environment to build and test the Valkey GLIDE Ruby client (`valkey-rb`).
4
4
 
5
5
  ## Development Overview
6
6
 
@@ -43,7 +43,7 @@ valkey-glide-ruby/
43
43
  │ ├── setup # bundle install
44
44
  │ └── console # IRB with gem loaded
45
45
  ├── .github/workflows/
46
- │ ├── ci.yml # RuboCop + test matrix
46
+ │ ├── CI.yml # RuboCop + test matrix
47
47
  │ └── cd.yml # Build and publish gem
48
48
  ├── valkey.gemspec
49
49
  ├── Gemfile
@@ -54,7 +54,7 @@ valkey-glide-ruby/
54
54
 
55
55
  ### Software Dependencies
56
56
 
57
- - **Ruby** 3.0+
57
+ - **Ruby** 2.6+ (3.x recommended for development)
58
58
  - **Bundler**
59
59
  - **git**
60
60
  - **Valkey** or Redis OSS (for integration tests)
@@ -226,14 +226,13 @@ CI=1 bundle exec rake test:standalone
226
226
 
227
227
  ### SSL Tests
228
228
 
229
- TLS tests require a TLS server plus `TLS_CERT_DIR` pointing at its certs. Use
230
- `cluster_manager.py --tls` which will prepare a self-sign certs for use:
229
+ The preferred approach (matching CI and all other GLIDE clients) uses `cluster_manager.py`:
231
230
 
232
231
  ```bash
233
232
  # Start a TLS-only server on port 6380 (generates certs in valkey-glide/utils/tls_crts/)
234
233
  python3 valkey-glide/utils/cluster_manager.py --tls start -r 0 -p 6380 --prefix tls-standalone
235
234
 
236
- # Point tests at the generated certs (required — the TLS tests raise if unset)
235
+ # Point tests at the generated certs
237
236
  export TLS_CERT_DIR=$(pwd)/valkey-glide/utils/tls_crts
238
237
 
239
238
  # Run tests
@@ -243,8 +242,12 @@ bundle exec rake test:standalone
243
242
  python3 valkey-glide/utils/cluster_manager.py --tls stop --prefix tls-standalone
244
243
  ```
245
244
 
246
- If you don't want to run the TLS tests, set `SKIP_TLS_TESTS=true` and they are
247
- skipped gracefully (this is what macOS CI does).
245
+ Alternatively, for local development without Python, generate certs and start manually:
246
+
247
+ ```bash
248
+ ruby test/fixtures/ssl/generate_certs.rb
249
+ # Then start a TLS Valkey server on port 6380 using those certs
250
+ ```
248
251
 
249
252
  ### Module Tests (JSON, Bloom, Search)
250
253
 
@@ -267,7 +270,7 @@ VALKEY_PORT=6379 TIMEOUT=10 bundle exec rake test:standalone
267
270
  bundle exec rubocop
268
271
  ```
269
272
 
270
- CI runs RuboCop on every push and pull request (see `.github/workflows/ci.yml`).
273
+ CI runs RuboCop on every push and pull request (see `.github/workflows/CI.yml`).
271
274
 
272
275
  Auto-correct safe offenses:
273
276
 
@@ -347,13 +350,13 @@ bundle exec ruby test/valkey/test_opentelemetry.rb
347
350
 
348
351
  ## CI Overview
349
352
 
350
- GitHub Actions (`.github/workflows/ci.yml`):
353
+ GitHub Actions (`.github/workflows/CI.yml`):
351
354
 
352
355
  | Job | Matrix |
353
356
  |-----|--------|
354
357
  | `lint` | Ruby 3.3, RuboCop |
355
- | `standalone` | Ruby 3.0–3.4 + JRuby; Valkey 7.2, 8, 8.1 |
356
- | `cluster` | Ruby 3.0–3.4; grokzen/redis-cluster |
358
+ | `standalone` | Ruby 2.6–3.4 + JRuby; Valkey 7.2, 8, 8.1 |
359
+ | `cluster` | Ruby 2.6–3.4; grokzen/redis-cluster |
357
360
 
358
361
  ## Building the Gem Locally
359
362
 
@@ -372,7 +375,7 @@ rake native:package
372
375
  gem build valkey.gemspec
373
376
 
374
377
  # 4. Install locally
375
- gem install ./valkey-glide-rb-*.gem
378
+ gem install ./valkey-rb-*.gem
376
379
  ```
377
380
 
378
381
  ### What `rake native:package` Does
@@ -406,18 +409,18 @@ To build for a different platform, you must build on that platform (or use cross
406
409
 
407
410
  ```bash
408
411
  # Unpack and inspect
409
- gem unpack valkey-glide-rb-*.gem --target=gem-contents
412
+ gem unpack valkey-rb-*.gem --target=gem-contents
410
413
  find gem-contents -name "libglide_ffi.*"
411
414
 
412
415
  # Or list files in the gem
413
- gem spec valkey-glide-rb-*.gem files
416
+ gem spec valkey-rb-*.gem files
414
417
  ```
415
418
 
416
419
  ### Install and Test
417
420
 
418
421
  ```bash
419
422
  # Install the locally built gem
420
- gem install ./valkey-glide-rb-*.gem
423
+ gem install ./valkey-rb-*.gem
421
424
 
422
425
  # Test it works (requires Valkey running)
423
426
  ruby -e "require 'valkey'; c = Valkey.new; puts c.ping; c.close"
@@ -440,7 +443,7 @@ ruby -e "require 'valkey'; c = Valkey.new; puts c.ping; c.close"
440
443
  | `LoadError` / FFI library not found | Confirm `lib/valkey/libglide_ffi.{so,dylib}` exists and matches your OS/arch. |
441
444
  | Wrong architecture after FFI rebuild | Rebuild `glide-ffi` on the target platform; do not copy Linux `.so` to macOS. |
442
445
  | Cluster tests flaky | Wait for `cluster_state:ok`; increase `TIMEOUT` env var. |
443
- | SSL test failures / `TLS_CERT_DIR is not set` | Start a TLS server via `cluster_manager.py --tls` and `export TLS_CERT_DIR=...` (see SSL Tests above), or set `SKIP_TLS_TESTS=true`. |
446
+ | SSL test failures | Use `cluster_manager.py --tls` (see SSL Tests above), or regenerate local certs: `ruby test/fixtures/ssl/generate_certs.rb`. |
444
447
  | Pipeline / MULTI crashes | Transaction commands in `pipelined` use sequential fallback by design. |
445
448
 
446
449
  ## Recommended Editor Extensions
data/README.md CHANGED
@@ -1,7 +1,6 @@
1
-
2
1
  # Valkey GLIDE for Ruby
3
2
 
4
- Valkey General Language Independent Driver for the Enterprise (GLIDE) is the official open-source Valkey client library, proudly part of the [Valkey](https://valkey.io) organization. The Ruby gem (`valkey-glide-rb`) wraps [Valkey GLIDE Core](https://github.com/valkey-io/valkey-glide), delivering GLIDE performance, reliability, and enterprise features.
3
+ Valkey General Language Independent Driver for the Enterprise (GLIDE) is the official open-source Valkey client library, proudly part of the [Valkey](https://valkey.io) organization. The Ruby gem (`valkey-rb`) wraps [Valkey GLIDE Core](https://github.com/valkey-io/valkey-glide) (Rust) and aims to be a **drop-in replacement for [redis-rb](https://github.com/redis/redis-rb)** while delivering GLIDE performance, reliability, and enterprise features.
5
4
 
6
5
  ## Why Choose Valkey GLIDE?
7
6
 
@@ -10,6 +9,7 @@ Valkey General Language Independent Driver for the Enterprise (GLIDE) is the off
10
9
  - **Performance**: Optimized for high performance and low latency via the Rust-based GLIDE core.
11
10
  - **High Availability**: Cluster-aware routing, reconnection, and fault tolerance.
12
11
  - **Cross-Language Consistency**: Same core driver as Python, Java, Node.js, and Go clients.
12
+ - **Drop-in Replacement**: Familiar redis-rb-style API (`Valkey.new`, command methods, `pipelined`, URL parsing).
13
13
  - **Observability**: Native OpenTelemetry tracing and client statistics.
14
14
 
15
15
  ## Documentation
@@ -30,31 +30,41 @@ Valkey General Language Independent Driver for the Enterprise (GLIDE) is the off
30
30
 
31
31
  ### System Requirements
32
32
 
33
- - glibc 2.17+ or musl 1.2.3+
34
- - Ruby 3.0+
33
+ The release of Valkey GLIDE Ruby was tested on the following platforms:
34
+
35
+ **Linux:**
36
+
37
+ - Ubuntu 20+ (x86_64/amd64 and arm64/aarch64)
38
+ - Amazon Linux 2 (AL2) and 2023 (AL2023) (x86_64)
39
+ - Alpine Linux 3.18+ (x86_64 and arm64/aarch64) — musl libc
40
+
41
+ **macOS:**
35
42
 
36
- #### Supported OS
43
+ - macOS 14.7+ (Apple silicon / aarch64)
44
+ - macOS 13.7+ (x86_64 / amd64)
37
45
 
38
- The following platforms are tested in CI:
39
- - Ubuntu 24 (x86_64 and arm64)
40
- - Alpine Linux 3 (x86_64 and arm64, via musl targets)
41
- - macOS 14+ (Apple silicon / arm64)
46
+ ### Ruby Supported Versions
42
47
 
43
- **Notes:** valkey-glide-rb gem only support ARM MacOS. For Intel Mac users
44
- you will need to build the client locally.
48
+ | Ruby Version | MRI | JRuby |
49
+ |--------------|-----|-------|
50
+ | 2.6 | ✓ | - |
51
+ | 2.7 | ✓ | - |
52
+ | 3.0 – 3.4 | ✓ | ✓ |
53
+
54
+ Minimum Ruby version: **2.6.0** (see `valkey.gemspec`).
45
55
 
46
56
  ### Installation and Setup
47
57
 
48
58
  Install from RubyGems:
49
59
 
50
60
  ```bash
51
- gem install valkey-glide-rb
61
+ gem install valkey-rb
52
62
  ```
53
63
 
54
64
  Or add to your `Gemfile`:
55
65
 
56
66
  ```ruby
57
- gem "valkey-glide-rb"
67
+ gem "valkey-rb"
58
68
  ```
59
69
 
60
70
  Verify installation:
@@ -83,25 +93,16 @@ client.get("mykey")
83
93
  client.close
84
94
  ```
85
95
 
86
- ### Standalone with URL
87
-
88
- Accepted URL schemes: `redis://`, `rediss://` (TLS), `valkey://`, `valkeys://` (TLS).
96
+ ### Standalone with URL (redis-rb compatible)
89
97
 
90
98
  ```ruby
91
99
  client = Valkey.new(url: "redis://localhost:6379/0")
92
- # Valkey-native scheme (matches valkey-cli -u):
93
- # valkey://localhost:6379/0
94
- # TLS variants:
95
- # rediss://user:password@localhost:6380/0
96
- # valkeys://user:password@localhost:6380/0
100
+ # TLS: rediss://user:password@localhost:6380/0
97
101
 
98
102
  client.ping
99
103
  # => "PONG"
100
104
  ```
101
105
 
102
- Unparseable URLs, unsupported schemes, and URLs without a host raise
103
- `ArgumentError` — they no longer fall back to `127.0.0.1:6379` silently.
104
-
105
106
  ### Cluster Mode
106
107
 
107
108
  ```ruby
@@ -174,28 +175,27 @@ client.call("SET", "k", "v", nx: false, ex: nil)
174
175
  `call_v` takes the whole command as a single Array (no keyword flags) — useful when the command is
175
176
  built dynamically. Both return the raw reply with no type-casting based on the command name.
176
177
 
177
- ### Connection Options
178
+ ### Connection Options (redis-rb compatible)
178
179
 
179
180
  | Option | Description |
180
181
  |--------|-------------|
181
182
  | `host`, `port` | Server address (default `127.0.0.1:6379`) |
182
- | `url` | `redis://`, `rediss://`, `valkey://`, or `valkeys://` URI (merged with explicit options) |
183
+ | `url` | `redis://` or `rediss://` URI (merged with explicit options) |
183
184
  | `db` | Database index (standalone only) |
184
185
  | `password`, `username` | Authentication |
185
186
  | `timeout` | Request timeout in seconds (default `5.0`) |
186
187
  | `connect_timeout` | Connection timeout in seconds |
187
- | `ssl`| Enable TLS if true |
188
- | `ssl_params` | TLS options {`ca_file`, `cert`, `key`, `ca_path`, `root_certs`} |
188
+ | `ssl`, `ssl_params` | TLS (`ca_file`, `cert`, `key`, `ca_path`, `root_certs`) |
189
189
  | `cluster_mode` | Enable cluster client |
190
190
  | `nodes` | Array of `{ host:, port: }` hashes |
191
191
  | `protocol` | `:resp2` (default) or `:resp3` |
192
192
  | `client_name` | `CLIENT SETNAME` value |
193
193
  | `reconnect_attempts`, `reconnect_delay`, `reconnect_delay_max` | Connection retry strategy |
194
- | `read_from` | Read routing: the `Valkey::ReadFrom::*` constants: `PRIMARY`, `PREFER_REPLICA`, `AZ_AFFINITY`, `AZ_AFFINITY_REPLICAS_AND_PRIMARY`.`AZ_AFFINITY`/`AZ_AFFINITY_REPLICAS_AND_PRIMARY` require `client_az` to also be set. |
195
- | `client_az` | Availability-zone identifier for `AZ_AFFINITY` / `AZ_AFFINITY_REPLICAS_AND_PRIMARY` routing (e.g. `"us-west-2a"`) |
196
- | `inflight_requests_limit` | Maximum concurrent in-flight requests (non-negative integer) |
197
- | `lazy_connect` | Delay the actual connection until the first command is sent |
198
- | `periodic_checks` | Cluster topology health checks: `{ manual_interval: { duration_in_sec: N } }` or `{ disabled: true }`. Accepted (as a no-op) on standalone connections. |
194
+ | `read_from` *(GLIDE-native)* | Read routing: `:primary`, `:prefer_replica`, `:az_affinity`, `:az_affinity_replicas_and_primary` symbols, the exact-match GLIDE strings (e.g. `"PreferReplica"`), or the `Valkey::ReadFrom::*` constants (e.g. `Valkey::ReadFrom::PREFER_REPLICA`). `:az_affinity`/`:az_affinity_replicas_and_primary` require `client_az` to also be set. `LowestLatency` is a valid GLIDE value but not yet usable via the vendored native library. |
195
+ | `client_az` *(GLIDE-native)* | Availability-zone identifier for `:az_affinity` / `:az_affinity_replicas_and_primary` routing (e.g. `"us-west-2a"`) |
196
+ | `inflight_requests_limit` *(GLIDE-native)* | Maximum concurrent in-flight requests (non-negative integer) |
197
+ | `lazy_connect` *(GLIDE-native)* | Delay the actual connection until the first command is sent |
198
+ | `periodic_checks` *(GLIDE-native)* | Cluster topology health checks: `{ manual_interval: { duration_in_sec: N } }` or `{ disabled: true }`. Accepted (as a no-op) on standalone connections. |
199
199
 
200
200
  ```ruby
201
201
  client = Valkey.new(
@@ -311,8 +311,8 @@ Available keys: `:total_connections`, `:total_clients`, `:total_values_compresse
311
311
 
312
312
  ## Pub/Sub
313
313
 
314
- Pub/Sub is currently not supported and is not ready for use and is planned for future release.
315
- See https://github.com/valkey-io/valkey-glide-ruby/issues/135
314
+ Pub/Sub uses a native callback registered at connection time. Configure subscriptions via command modules (`subscribe`, `psubscribe`, etc.). See [DEVELOPER.md](./DEVELOPER.md) and integration tests in `test/valkey/pubsub_commands_test.rb` for details.
315
+
316
316
  ## Layout of Ruby Code
317
317
 
318
318
  | Path | Purpose |
@@ -324,17 +324,17 @@ See https://github.com/valkey-io/valkey-glide-ruby/issues/135
324
324
  | `lib/valkey/pipeline.rb` | Pipeline command batching |
325
325
  | `test/valkey/` | Standalone integration tests |
326
326
  | `test/cluster/` | Cluster integration tests |
327
- | `test/lint/` | Shared lint tests (redis-rb convention patterns) |
327
+ | `test/lint/` | Shared lint tests (redis-rb compatibility patterns) |
328
328
 
329
- ## API Conventions
329
+ ## redis-rb Compatibility
330
330
 
331
- This client is **not** a drop-in replacement for redis-rb, but it follows familiar Ruby conventions to ease adoption:
331
+ This client mirrors redis-rb conventions where possible:
332
332
 
333
333
  - `Valkey.new` with `url`, `host`, `port`, `db`, `ssl_params`
334
- - Conventional command method names and argument ordering
334
+ - Command method names and argument ordering aligned with redis-rb
335
335
  - `pipelined`, `multi` / `exec`, `disconnect!` (alias of `close`)
336
336
 
337
- APIs and behavior may differ from redis-rb; verify against your usage. See the [command implementation wiki](https://github.com/valkey-io/valkey-glide-ruby/wiki/The-implementation-status-of-the-Valkey-commands) for coverage.
337
+ Not every redis-rb API is implemented yet. See the [command implementation wiki](https://github.com/valkey-io/valkey-glide-ruby/wiki/The-implementation-status-of-the-Valkey-commands) for coverage.
338
338
 
339
339
  ## Building and Testing
340
340
 
data/Rakefile CHANGED
@@ -125,12 +125,9 @@ namespace :test do
125
125
  # Exclude module directories (valkey/, lint/) from lost_tests check
126
126
  # These contain reusable test modules, not standalone test files
127
127
  module_dirs = %w[valkey lint]
128
- # Standalone scripts run directly (not via a test group) — see cd.yml
129
- standalone_scripts = %w[test/smoke_test.rb]
130
128
  lost_tests = Dir["test/**/*_test.rb"] -
131
129
  groups.map { |g| Dir["test/#{g}/**/*_test.rb"] }.flatten -
132
- module_dirs.map { |d| Dir["test/#{d}/**/*_test.rb"] }.flatten -
133
- standalone_scripts
130
+ module_dirs.map { |d| Dir["test/#{d}/**/*_test.rb"] }.flatten
134
131
  abort "The following test files are in no group:\n#{lost_tests.join("\n")}" unless lost_tests.empty?
135
132
  end
136
133
 
@@ -124,9 +124,10 @@ class Valkey
124
124
 
125
125
  # Get information about the cluster.
126
126
  #
127
+ # @param route [Valkey::Route, nil] cluster routing. When routed, may return a Hash of node => value.
127
128
  # @return [Hash<String, String>] cluster information
128
- def cluster_info
129
- send_command(RequestType::CLUSTER_INFO, []) do |reply|
129
+ def cluster_info(route: nil)
130
+ send_command(RequestType::CLUSTER_INFO, [], route: route) do |reply|
130
131
  if reply.is_a?(Hash)
131
132
  reply.transform_values { |v| Utils::HashifyInfo.call(v) }
132
133
  else
@@ -145,9 +146,10 @@ class Valkey
145
146
 
146
147
  # Get information about cluster links.
147
148
  #
149
+ # @param route [Valkey::Route, nil] cluster routing. When routed, may return a Hash of node => value.
148
150
  # @return [Array<Hash>] array of link information
149
- def cluster_links
150
- send_command(RequestType::CLUSTER_LINKS, [])
151
+ def cluster_links(route: nil)
152
+ send_command(RequestType::CLUSTER_LINKS, [], route: route)
151
153
  end
152
154
 
153
155
  # Meet another node in the cluster.
@@ -161,23 +163,26 @@ class Valkey
161
163
 
162
164
  # Get the ID of the current node.
163
165
  #
166
+ # @param route [Valkey::Route, nil] cluster routing. When routed, may return a Hash of node => value.
164
167
  # @return [String] node ID
165
- def cluster_myid
166
- send_command(RequestType::CLUSTER_MY_ID, [])
168
+ def cluster_myid(route: nil)
169
+ send_command(RequestType::CLUSTER_MY_ID, [], route: route)
167
170
  end
168
171
 
169
172
  # Get the shard ID of the current node.
170
173
  #
174
+ # @param route [Valkey::Route, nil] cluster routing. When routed, may return a Hash of node => value.
171
175
  # @return [String] shard ID
172
- def cluster_myshardid
173
- send_command(RequestType::CLUSTER_MY_SHARD_ID, [])
176
+ def cluster_myshardid(route: nil)
177
+ send_command(RequestType::CLUSTER_MY_SHARD_ID, [], route: route)
174
178
  end
175
179
 
176
180
  # Get information about all nodes in the cluster.
177
181
  #
182
+ # @param route [Valkey::Route, nil] cluster routing. When routed, may return a Hash of node => value.
178
183
  # @return [Array<Hash>] array of node information
179
- def cluster_nodes
180
- send_command(RequestType::CLUSTER_NODES, []) do |reply|
184
+ def cluster_nodes(route: nil)
185
+ send_command(RequestType::CLUSTER_NODES, [], route: route) do |reply|
181
186
  if reply.is_a?(Hash)
182
187
  reply.transform_values { |v| Utils::HashifyClusterNodes.call(v) }
183
188
  else
@@ -243,9 +248,10 @@ class Valkey
243
248
 
244
249
  # Get information about cluster shards.
245
250
  #
251
+ # @param route [Valkey::Route, nil] cluster routing. When routed, may return a Hash of node => value.
246
252
  # @return [Array<Hash>] array of shard information
247
- def cluster_shards
248
- send_command(RequestType::CLUSTER_SHARDS, [])
253
+ def cluster_shards(route: nil)
254
+ send_command(RequestType::CLUSTER_SHARDS, [], route: route)
249
255
  end
250
256
 
251
257
  # Get information about slave nodes (deprecated, use cluster_replicas).