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.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -10
- data/AGENTS.md +15 -31
- data/CHANGELOG.md +0 -9
- data/CLAUDE.md +1 -1
- data/CONTRIBUTING.md +3 -3
- data/DEVELOPER.md +20 -17
- data/README.md +40 -40
- data/Rakefile +1 -4
- data/lib/valkey/commands/cluster_commands.rb +18 -12
- data/lib/valkey/commands/connection_commands.rb +68 -28
- data/lib/valkey/commands/function_commands.rb +15 -13
- data/lib/valkey/commands/generic_commands.rb +8 -17
- data/lib/valkey/commands/hash_commands.rb +13 -13
- data/lib/valkey/commands/list_commands.rb +77 -109
- data/lib/valkey/commands/pubsub_commands.rb +2 -4
- data/lib/valkey/commands/scripting_commands.rb +49 -127
- data/lib/valkey/commands/server_commands.rb +49 -42
- data/lib/valkey/commands/set_commands.rb +4 -4
- data/lib/valkey/commands/stream_commands.rb +10 -20
- data/lib/valkey/commands/string_commands.rb +61 -28
- data/lib/valkey/commands/transaction_commands.rb +10 -64
- data/lib/valkey/commands/vector_search_commands.rb +1 -1
- data/lib/valkey/commands.rb +4 -2
- data/lib/valkey/native/aarch64-apple-darwin/libglide_ffi.dylib +0 -0
- data/lib/valkey/native/aarch64-unknown-linux-gnu/libglide_ffi.so +0 -0
- data/lib/valkey/native/aarch64-unknown-linux-musl/libglide_ffi.so +0 -0
- data/lib/valkey/native/x86_64-unknown-linux-gnu/libglide_ffi.so +0 -0
- data/lib/valkey/native/x86_64-unknown-linux-musl/libglide_ffi.so +0 -0
- data/lib/valkey/opentelemetry.rb +5 -26
- data/lib/valkey/pipeline.rb +2 -171
- data/lib/valkey/pubsub_callback.rb +0 -13
- data/lib/valkey/read_from.rb +8 -1
- data/lib/valkey/request_type.rb +2 -0
- data/lib/valkey/route.rb +0 -2
- data/lib/valkey/utils.rb +76 -71
- data/lib/valkey/version.rb +1 -1
- data/lib/valkey.rb +104 -163
- metadata +4 -5
- data/lib/valkey/future.rb +0 -85
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 31e06a1cd3c0ecb6cd124d2d65c232cd080f5d5b9c3beaec4edac11ca8c9ddd4
|
|
4
|
+
data.tar.gz: a72a457f3533a2ee91c3b4d3a33633d4a5b19f73482c71fd6405c7c5229b3a1e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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:
|
|
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-
|
|
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-
|
|
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/` —
|
|
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-
|
|
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`
|
|
87
|
-
| SSL tests | TLS Valkey on port `6380` +
|
|
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
|
|
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
|
|
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
|
|
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/
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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/
|
|
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-
|
|
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
|
-
│ ├──
|
|
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.
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
247
|
-
|
|
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/
|
|
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/
|
|
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
|
|
356
|
-
| `cluster` | Ruby
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
|
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-
|
|
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
|
-
|
|
34
|
-
|
|
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
|
-
|
|
43
|
+
- macOS 14.7+ (Apple silicon / aarch64)
|
|
44
|
+
- macOS 13.7+ (x86_64 / amd64)
|
|
37
45
|
|
|
38
|
-
|
|
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
|
-
|
|
44
|
-
|
|
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-
|
|
61
|
+
gem install valkey-rb
|
|
52
62
|
```
|
|
53
63
|
|
|
54
64
|
Or add to your `Gemfile`:
|
|
55
65
|
|
|
56
66
|
```ruby
|
|
57
|
-
gem "valkey-
|
|
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
|
-
#
|
|
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
|
|
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
|
|
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
|
|
195
|
-
| `client_az` | Availability-zone identifier for `
|
|
196
|
-
| `inflight_requests_limit`
|
|
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
|
|
315
|
-
|
|
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
|
|
327
|
+
| `test/lint/` | Shared lint tests (redis-rb compatibility patterns) |
|
|
328
328
|
|
|
329
|
-
##
|
|
329
|
+
## redis-rb Compatibility
|
|
330
330
|
|
|
331
|
-
This client
|
|
331
|
+
This client mirrors redis-rb conventions where possible:
|
|
332
332
|
|
|
333
333
|
- `Valkey.new` with `url`, `host`, `port`, `db`, `ssl_params`
|
|
334
|
-
-
|
|
334
|
+
- Command method names and argument ordering aligned with redis-rb
|
|
335
335
|
- `pipelined`, `multi` / `exec`, `disconnect!` (alias of `close`)
|
|
336
336
|
|
|
337
|
-
|
|
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).
|