valkey-glide-rb 1.0.0 → 1.1.0.pre.rc2

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 (64) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +1 -1
  3. data/.yard-lint.yml +157 -0
  4. data/AGENTS.md +133 -52
  5. data/CHANGELOG.md +64 -11
  6. data/CLAUDE.md +2 -123
  7. data/CONTRIBUTING.md +20 -83
  8. data/DEVELOPER.md +39 -418
  9. data/LICENSE +201 -0
  10. data/LICENSES/redis-rb-MIT.txt +20 -0
  11. data/NOTICE +5 -0
  12. data/README.md +25 -228
  13. data/Rakefile +66 -11
  14. data/docs/DOCUMENTING.md +24 -0
  15. data/docs/TESTING.md +61 -0
  16. data/examples/README.md +32 -1
  17. data/examples/iam_authentication.rb +52 -0
  18. data/lib/valkey/bindings.rb +8 -3
  19. data/lib/valkey/commands/bitmap_commands.rb +34 -14
  20. data/lib/valkey/commands/cluster_commands.rb +42 -23
  21. data/lib/valkey/commands/connection_commands.rb +52 -33
  22. data/lib/valkey/commands/function_commands.rb +44 -30
  23. data/lib/valkey/commands/generic_commands.rb +117 -72
  24. data/lib/valkey/commands/geo_commands.rb +20 -13
  25. data/lib/valkey/commands/hash_commands.rb +95 -56
  26. data/lib/valkey/commands/hyper_log_log_commands.rb +6 -3
  27. data/lib/valkey/commands/json_commands.rb +102 -81
  28. data/lib/valkey/commands/list_commands.rb +58 -48
  29. data/lib/valkey/commands/module_commands.rb +13 -10
  30. data/lib/valkey/commands/pubsub_commands.rb +416 -114
  31. data/lib/valkey/commands/scripting_commands.rb +76 -34
  32. data/lib/valkey/commands/server_commands.rb +199 -152
  33. data/lib/valkey/commands/set_commands.rb +65 -22
  34. data/lib/valkey/commands/sorted_set_commands.rb +129 -117
  35. data/lib/valkey/commands/stream_commands.rb +159 -159
  36. data/lib/valkey/commands/string_commands.rb +70 -30
  37. data/lib/valkey/commands/transaction_commands.rb +44 -17
  38. data/lib/valkey/commands/vector_search_commands.rb +271 -209
  39. data/lib/valkey/commands.rb +2 -3
  40. data/lib/valkey/errors.rb +15 -0
  41. data/lib/valkey/iam_auth_config.rb +36 -0
  42. data/lib/valkey/native/aarch64-apple-darwin/libglide_ffi.dylib +0 -0
  43. data/lib/valkey/native/aarch64-unknown-linux-gnu/libglide_ffi.so +0 -0
  44. data/lib/valkey/native/aarch64-unknown-linux-musl/libglide_ffi.so +0 -0
  45. data/lib/valkey/native/x86_64-unknown-linux-gnu/libglide_ffi.so +0 -0
  46. data/lib/valkey/native/x86_64-unknown-linux-musl/libglide_ffi.so +0 -0
  47. data/lib/valkey/opentelemetry.rb +84 -2
  48. data/lib/valkey/pipeline.rb +38 -1
  49. data/lib/valkey/pubsub/pubsub_message.rb +31 -0
  50. data/lib/valkey/pubsub/pubsub_receiver.rb +135 -0
  51. data/lib/valkey/pubsub/pubsub_state.rb +71 -0
  52. data/lib/valkey/read_from.rb +1 -0
  53. data/lib/valkey/request_type.rb +11 -0
  54. data/lib/valkey/search/aggregate.rb +291 -0
  55. data/lib/valkey/search/create_options.rb +57 -0
  56. data/lib/valkey/search/fields.rb +215 -0
  57. data/lib/valkey/search/info.rb +33 -0
  58. data/lib/valkey/search/query.rb +249 -0
  59. data/lib/valkey/search.rb +96 -0
  60. data/lib/valkey/service_type.rb +12 -0
  61. data/lib/valkey/version.rb +1 -1
  62. data/lib/valkey.rb +285 -50
  63. metadata +23 -9
  64. data/lib/valkey/pubsub_callback.rb +0 -23
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4f24251c31a635bac9aff04c0f4ae8027c9badf52acc0547f4dc463515b3eba7
4
- data.tar.gz: dd7e0050d647a2782a551d9266c96ff73a9a6d3c9405dc2eecb921a6359e5aff
3
+ metadata.gz: dfc81a09f2d8b032a39e6f0262847803a676610d16ea6f61dd0394e69c715b2c
4
+ data.tar.gz: 6737025091639c50123942649e2cd96bf47e702b3949eb1352e566e88be09487
5
5
  SHA512:
6
- metadata.gz: ee2da87f8c6c1806541476ccd752750c7320561c1010373fb7a9f679d41a321642adc6f3833b8dd04a142088a47b0ed6e9a3df03b8e34bd3c7cd0d8a2789f016
7
- data.tar.gz: 8d862e3f9d1709a09a49dc8a2523afd5b61241a2068d73a64b2aa7db5e2d6c04d0402318877e21c7f15f96d5146c4e060b5a5085bb4236f99999012757684e8e
6
+ metadata.gz: 181f412f7a9836b5bcb766ca9948828b25ca170b19ae9b60a398a4345f90e0bc6f5f6a5feb81f37b0da9cd81ad6d817770af67e794867e7f92e067753c1e43b8
7
+ data.tar.gz: 0ee99333bb440ea2fe407dac753eda7c69228eb21097493917974495729e523e883edc6305edb42604cad17e3a90948608302ba8394ec64d69e8b20d2e547f68
data/.rubocop_todo.yml CHANGED
@@ -17,6 +17,6 @@ Metrics/BlockLength:
17
17
  # Offense count: 1
18
18
  # Configuration parameters: CountComments, CountAsOne.
19
19
  Metrics/ClassLength:
20
- Max: 111
20
+ Max: 200
21
21
  Exclude:
22
22
  - 'lib/valkey.rb'
data/.yard-lint.yml ADDED
@@ -0,0 +1,157 @@
1
+ # Keep this configuration limited to the API documentation format described in CONTRIBUTING.md. Validators outside that format stay disabled.
2
+ AllValidators:
3
+ Exclude:
4
+ - "test/**/*"
5
+ - "valkey-glide/**/*"
6
+ FailOnSeverity: convention
7
+ MinCoverage: 0
8
+
9
+ Documentation:
10
+ Enabled: false
11
+
12
+ Tags:
13
+ Enabled: false
14
+
15
+ Warnings:
16
+ Enabled: false
17
+
18
+ Semantic:
19
+ Enabled: false
20
+
21
+ Documentation/UndocumentedObjects:
22
+ Enabled: false
23
+
24
+ Documentation/UndocumentedMethodArguments:
25
+ Enabled: true
26
+ Severity: error
27
+ SkipFullyUndocumented: true
28
+ # YARD associates the preceding attr_reader docs with two undocumented
29
+ # two-argument initializers, so they do not appear fully undocumented here.
30
+ AllowedMethods:
31
+ - "initialize/2"
32
+
33
+ Documentation/MissingReturn:
34
+ # This validator also reports fully undocumented methods and has no equivalent
35
+ # to UndocumentedMethodArguments/SkipFullyUndocumented.
36
+ Enabled: false
37
+
38
+ Documentation/OrphanedDocComment:
39
+ Enabled: true
40
+ Severity: error
41
+
42
+ Documentation/EmptyCommentLine:
43
+ Enabled: true
44
+ Severity: convention
45
+ EnabledPatterns:
46
+ Leading: true
47
+ Trailing: true
48
+
49
+ Documentation/BlankLineBeforeDefinition:
50
+ Enabled: true
51
+ Severity: convention
52
+ OrphanedSeverity: convention
53
+ EnabledPatterns:
54
+ SingleBlankLine: true
55
+ OrphanedDocs: true
56
+
57
+ Documentation/LineLength:
58
+ Enabled: true
59
+ Severity: convention
60
+ MaxLength: 120
61
+
62
+ Tags/Order:
63
+ Enabled: true
64
+ Severity: error
65
+ EnforcedOrder:
66
+ - example
67
+ - param
68
+ - option
69
+ - yield
70
+ - yieldparam
71
+ - yieldreturn
72
+ - return
73
+ - raise
74
+ - since
75
+ - see
76
+ - note
77
+ - deprecated
78
+ - todo
79
+ - api
80
+
81
+ Tags/InvalidTypes:
82
+ Enabled: true
83
+ Severity: error
84
+ ValidatedTags:
85
+ - param
86
+ - option
87
+ - return
88
+
89
+ Tags/TypeSyntax:
90
+ Enabled: true
91
+ Severity: error
92
+ ValidatedTags:
93
+ - param
94
+ - option
95
+ - return
96
+ - yieldparam
97
+ - yieldreturn
98
+
99
+ Tags/TagTypePosition:
100
+ Enabled: true
101
+ Severity: error
102
+ CheckedTags:
103
+ - param
104
+ - option
105
+ EnforcedStyle: type_first
106
+
107
+ Tags/TagGroupSeparator:
108
+ Enabled: true
109
+ Severity: convention
110
+ TagGroups:
111
+ example:
112
+ - example
113
+ param:
114
+ - param
115
+ - option
116
+ yield:
117
+ - yield
118
+ - yieldparam
119
+ - yieldreturn
120
+ return:
121
+ - return
122
+ error:
123
+ - raise
124
+ since:
125
+ - since
126
+ reference:
127
+ - see
128
+ note:
129
+ - note
130
+ - deprecated
131
+ - todo
132
+ - api
133
+ RequireAfterDescription: true
134
+
135
+ Tags/InformalNotation:
136
+ Enabled: true
137
+ Severity: warning
138
+
139
+ Warnings/SyntaxError:
140
+ Enabled: true
141
+ Severity: error
142
+
143
+ Warnings/UnknownTag:
144
+ Enabled: true
145
+ Severity: error
146
+
147
+ Warnings/InvalidTagFormat:
148
+ Enabled: true
149
+ Severity: error
150
+
151
+ Warnings/DuplicatedParameterName:
152
+ Enabled: true
153
+ Severity: error
154
+
155
+ Warnings/UnknownParameterName:
156
+ Enabled: true
157
+ Severity: error
data/AGENTS.md CHANGED
@@ -10,23 +10,25 @@ This is the **Ruby client** for Valkey GLIDE, published as the `valkey-glide-rb`
10
10
 
11
11
  **Build System:** Bundler, Rake, RubyGems
12
12
 
13
- **Architecture:** Ruby wrapper around `glide-ffi` (`libglide_ffi.so` / `.dylib`) — same FFI path as Go and Python sync clients
13
+ **Architecture:** Ruby wrapper around `glide-ffi` (`libglide_ffi.so` / `.dylib`), the same FFI path as Go and Python sync clients
14
14
 
15
15
  **Key Components:**
16
16
 
17
- - `lib/valkey.rb` — Main client, pipelining, response conversion
18
- - `lib/valkey/bindings.rb` — FFI bindings
19
- - `lib/valkey/commands/` — Command modules
20
- - `lib/valkey/opentelemetry.rb` — Native OTel configuration
21
- - `test/valkey/` — Standalone integration tests
22
- - `test/cluster/` — Cluster integration tests
23
- - `test/lint/` — Lint suites
17
+ - `lib/valkey.rb`: Main client, pipelining, response conversion
18
+ - `lib/valkey/bindings.rb`: FFI bindings
19
+ - `lib/valkey/commands/`: Command modules
20
+ - `lib/valkey/opentelemetry.rb`: Native OTel configuration
21
+ - `test/unit/`: Server-free unit tests
22
+ - `test/integration/standalone/`: Standalone integration tests
23
+ - `test/integration/cluster/`: Cluster integration tests
24
+ - `test/integration/valkey/`: Shared valkey-glide-specific test modules
25
+ - `test/lint/`: Lint suites
24
26
 
25
27
  ## Architecture Quick Facts
26
28
 
27
29
  **Core Implementation:** Ruby wrapper around glide-core via `glide-ffi` cdylib
28
30
 
29
- **Client Types:** `Valkey` — standalone or cluster (`cluster_mode: true`)
31
+ **Client Types:** `Valkey`, standalone or cluster (`cluster_mode: true`)
30
32
 
31
33
  **API Style:** Synchronous, blocking calls.
32
34
 
@@ -35,13 +37,46 @@ This is the **Ruby client** for Valkey GLIDE, published as the `valkey-glide-rb`
35
37
  **Supported Platforms:**
36
38
 
37
39
  - Linux: Ubuntu 20+, Amazon Linux 2/2023 (x86_64, aarch64)
38
- - Alpine Linux 3.18+ (x86_64, aarch64) — musl libc
40
+ - Alpine Linux 3.18+ (x86_64, aarch64), musl libc
39
41
  - macOS: 13.7+ (x86_64), 14.7+ (aarch64)
40
42
 
41
- **Ruby Versions:** 3.0, 3.1, 3.2, 3.3, 3.4, JRuby (CI matrix)
43
+ **Ruby Versions:** 3.0, 3.1, 3.2, 3.3, 3.4. Minimum is 3.0 per `valkey.gemspec`.
42
44
 
43
45
  **Gem name:** `valkey-glide-rb` on RubyGems
44
46
 
47
+ ## Context Retrieval
48
+
49
+ When working on a feature, read these paths first:
50
+
51
+ | Topic | Read first |
52
+ |-------|------------|
53
+ | Connection / options | `lib/valkey.rb` (`#initialize`), `test/lint/connection_options.rb` |
54
+ | New command | `lib/valkey/request_type.rb`, matching `lib/valkey/commands/*.rb`, `test/lint/*` |
55
+ | Adding/reviewing tests | `docs/TESTING.md` in full, then the relevant test files |
56
+ | Pipelining / batch | `lib/valkey.rb` (`pipelined`, `send_batch_commands`), `lib/valkey/pipeline.rb` |
57
+ | OpenTelemetry | `lib/valkey/opentelemetry.rb`, `test/integration/valkey/opentelemetry_test.rb` |
58
+ | FFI / errors | `lib/valkey/bindings.rb`, `lib/valkey/errors.rb` |
59
+ | Cluster | `test/support/helper/cluster.rb`, `test/integration/cluster/` |
60
+ | Upstream semantics | [valkey-glide glide-core](https://github.com/valkey-io/valkey-glide/tree/main/glide-core), peer client in `go/` or `python/glide-sync/` |
61
+
62
+ ## Quality Gates (Agent Checklist)
63
+
64
+ - [ ] Used `docs/TESTING.md` as the authoritative reference for test implementations.
65
+ - [ ] `bundle exec rubocop` passes
66
+ - [ ] `bundle exec rake lint:yard`.
67
+ - [ ] Test servers were started/stopped via `cluster_manager.py` (never hand-launched or ad-hoc `docker run`)
68
+ - [ ] `bundle exec rake test:unit` passes (no server needed)
69
+ - [ ] `bundle exec rake test:standalone` passes (with Valkey running)
70
+ - [ ] `bundle exec rake test:cluster` passes (if cluster commands touched)
71
+ - [ ] New commands have tests in `test/integration/valkey/` and lint coverage where applicable
72
+ - [ ] `RequestType` matches glide-core enum
73
+ - [ ] No secrets or generated junk committed
74
+ - [ ] DCO signoff: `git log --format="%B" -n 1 | grep "Signed-off-by"`
75
+ - [ ] Conventional commit format used
76
+ - [ ] `CHANGELOG.md` updated for user-facing changes
77
+ - [ ] PR body follows `.github/pull_request_template.md` (all sections filled, checklist completed)
78
+ - [ ] Native lib rebuilt and copied if FFI/protobuf changed upstream
79
+
45
80
  ## Build and Test Rules (Agents)
46
81
 
47
82
  ### Preferred (Bundler / Rake)
@@ -52,9 +87,12 @@ bin/setup # bundle install
52
87
 
53
88
  # Linting
54
89
  bundle exec rubocop
90
+ bundle exec rake lint:yard
55
91
 
56
92
  # Testing
57
- bundle exec rake test # standalone + cluster
93
+ bundle exec rake test # unit + integration
94
+ bundle exec rake test:unit # unit only (no server needed)
95
+ bundle exec rake test:integration # standalone + cluster
58
96
  bundle exec rake test:standalone # standalone only
59
97
  bundle exec rake test:cluster # cluster only (needs nodes 7000-7005)
60
98
 
@@ -69,7 +107,7 @@ bundle exec bin/console
69
107
 
70
108
  ```bash
71
109
  # Run a single test file
72
- bundle exec ruby test/valkey/string_commands_test.rb
110
+ bundle exec ruby -Itest -Ilib test/integration/standalone/commands_test.rb
73
111
 
74
112
  # Run with custom port
75
113
  VALKEY_PORT=6379 TIMEOUT=10 bundle exec rake test:standalone
@@ -83,12 +121,17 @@ RUBYOPT="-I$(pwd)/lib" ruby -r valkey -e 'p Valkey.new.ping'
83
121
  | Suite | Server requirement |
84
122
  |-------|-------------------|
85
123
  | `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) |
124
+ | `test:cluster` | 6-node cluster on `127.0.0.1:7000`-`7005` (auto-started by the suite) |
87
125
  | SSL tests | TLS Valkey on port `6380` + `export TLS_CERT_DIR=...` (or `SKIP_TLS_TESTS=true`) |
88
126
  | Module tests | JSON, Bloom, Search modules loaded (see CI workflow) |
89
127
 
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:
128
+ ### Managing Test Servers
129
+
130
+ **Prefer `cluster_manager.py` for all test servers.** Start and stop standalone,
131
+ TLS, and cluster servers with `valkey-glide/utils/cluster_manager.py`. It's the
132
+ same tool CI uses, so ports, the test DB, TLS cert layout, and cluster topology
133
+ match CI. Use a manual `valkey-server`/`redis-server` launch or `docker run`
134
+ **only** when a scenario cannot be produced with `cluster_manager.py`.
92
135
 
93
136
  ```bash
94
137
  # Standalone on :6379
@@ -105,11 +148,36 @@ python3 valkey-glide/utils/cluster_manager.py --tls stop --prefix tls-standalone
105
148
 
106
149
  ### Rebuild Native FFI (when changing glide-core)
107
150
 
151
+ Prefer the Rake tasks; they init the submodule and set `GLIDE_NAME=GlideRuby` /
152
+ `GLIDE_VERSION` (from `lib/valkey/version.rb`) for `CLIENT SETINFO`:
153
+
108
154
  ```bash
109
- cd /path/to/valkey-glide/ffi
110
- cargo build --release
111
- cp target/release/libglide_ffi.so /path/to/valkey-glide-ruby/lib/valkey/ # Linux
112
- # cp target/release/libglide_ffi.dylib ... # macOS
155
+ rake native:build # release build in valkey-glide/ffi/target/release/
156
+ rake native:build_debug # debug build
157
+ rake native:package # copy built lib to lib/valkey/native/{arch}-{os}/ for gem packaging
158
+ rake native:clean # cargo clean
159
+ ```
160
+
161
+ The client (`lib/valkey/bindings.rb`) loads the native library from the first
162
+ location that exists, in this order:
163
+
164
+ 1. `valkey-glide/ffi/target/release/libglide_ffi.{so,dylib}`
165
+ 2. `valkey-glide/ffi/target/debug/libglide_ffi.{so,dylib}`
166
+ 3. `lib/valkey/native/{arch}-{os}/libglide_ffi.{so,dylib}` (bundled in the gem)
167
+ 4. `lib/valkey/libglide_ffi.{so,dylib}` (dev fallback)
168
+
169
+ Raw equivalent (only if not using Rake):
170
+
171
+ ```bash
172
+ # GLIDE_NAME/GLIDE_VERSION are baked in at compile time; omitting or mismatching them
173
+ # silently misreports LIB-NAME/LIB-VER. GLIDE_VERSION must match `lib/valkey/version.rb`.
174
+ # Resolve it from the repo root: the relative require will not resolve inside `valkey-glide/ffi`.
175
+ GLIDE_VERSION=$(ruby -r./lib/valkey/version -e 'print Valkey::VERSION') || exit 1
176
+ [ -n "$GLIDE_VERSION" ] || { echo "could not resolve GLIDE_VERSION" >&2; exit 1; }
177
+
178
+ cd valkey-glide/ffi
179
+ GLIDE_NAME=GlideRuby GLIDE_VERSION="$GLIDE_VERSION" cargo build --release
180
+ # release/debug builds under target/ are picked up automatically (order 1-2 above)
113
181
  ```
114
182
 
115
183
  ## Contribution Requirements
@@ -133,6 +201,28 @@ git config --global format.signOff true
133
201
 
134
202
  **Scopes:** `ruby`, or command family name when appropriate.
135
203
 
204
+ ### Pull Requests REQUIRED
205
+
206
+ When opening a PR, you MUST follow `.github/pull_request_template.md`. Read that
207
+ file first and fill in every section it defines and complete
208
+ its Checklist honestly. Do not substitute a free-form description; `gh pr create`
209
+ with a custom `--body` bypasses the template, so reproduce the template structure
210
+ in the body you pass.
211
+
212
+ ### Changelog REQUIRED
213
+
214
+ Follow the [changelog guidelines](./CONTRIBUTING.md#changelog).
215
+
216
+ General guidelines are:
217
+
218
+ - For each PR, add every user-facing change to the appropriate changelog section.
219
+ - Start each item with a verb.
220
+ - For new APIs, use `Added support for <API>`. Do not restate what each method does; the names and docs already say it.
221
+ - Future plans and internal refactors do not belong in the entry.
222
+ - Each change should be a concise one-sentence description of the change.
223
+ - Each change must be followed by a link to its PR.
224
+ - Do not retroactively change other changelog entries unless explicitly told to.
225
+
136
226
  ### Code Quality Requirements
137
227
 
138
228
  **RuboCop (required before commit):**
@@ -154,34 +244,35 @@ cargo fmt --manifest-path ./Cargo.toml --all
154
244
 
155
245
  ### Generated Outputs (Never Commit)
156
246
 
157
- - `*.gem` — built gem packages
158
- - `coverage/` — coverage reports
159
- - `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`)
161
- - Wrong-platform `libglide_ffi` binaries (build per OS/arch)
247
+ - `*.gem`: built gem packages
248
+ - `coverage/`: coverage reports
249
+ - `tmp/`, `test/tmp/`: temporary test artifacts
250
+ - SSL certs: never commit them; TLS tests read certs from `TLS_CERT_DIR` (generated by `cluster_manager.py --tls`)
251
+ - Wrong-platform `libglide_ffi` binaries (built per OS/arch during CD into `lib/valkey/native/{arch}-{os}/`)
162
252
 
163
253
  ### Ruby-Specific Rules
164
254
 
165
255
  - **Ruby 3.0+ Required:** Minimum per `valkey.gemspec`
166
- - **FFI dependency:** `ffi ~> 1.17.0` — do not break ABI without rebuilding native lib
256
+ - **FFI dependency:** `ffi ~> 1.17.0`; do not break ABI without rebuilding native lib
257
+ - **Blocking FFI bindings MUST pass `blocking: true`:** any `attach_function` in `lib/valkey/bindings.rb` that can wait — connect, command, batch, script, close. Ruby-FFI defaults to `blocking: false`, holding the GVL for the whole call: that stalls every other Ruby thread, and deadlocks if the call waits on something needing the GVL (a Pub/Sub callback). `create_client`/`create_client_from_uri` still need it. The `free_*`/`drop_*` and OTel span helpers don't — they never wait.
167
258
  - **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.
169
259
  - **Command args:** All FFI args are strings; convert types in Ruby before `send_command`
170
- - **Pipeline transactions:** `MULTI`/`EXEC`/`DISCARD` in `pipelined` use sequential fallback — do not remove without fixing FFI batch stability
260
+ - **Pipeline transactions:** `MULTI`/`EXEC`/`DISCARD` in `pipelined` use sequential fallback; do not remove without fixing FFI batch stability
171
261
  - **OpenTelemetry:** Init once per process via `Valkey::OpenTelemetry.init`; spans created in FFI layer
262
+ - **Comments:** Do not restate the code or narrate obvious steps. Explain intent, non-obvious constraints, or why the implementation is necessary.
172
263
 
173
264
  ### Command Implementation Guidelines
174
265
 
175
266
  1. Check `RequestType` in `lib/valkey/request_type.rb` against glide-core `request_type.rs`
176
267
  2. Add method to appropriate `lib/valkey/commands/*.rb` module
177
268
  3. Use `send_command(RequestType::..., args)`
178
- 4. Add tests: `test/valkey/` + `test/lint/` when applicable
179
- 5. Document with YARD comments + Valkey command link
269
+ 4. Add tests: `test/integration/valkey/` + `test/lint/` when applicable. MUST follow `docs/TESTING.md`
270
+ 5. MUST Follow the `docs/DOCUMENTING.md` on how to write public API docstring.
180
271
 
181
272
  ### Never Commit
182
273
 
183
274
  - Secrets, `.env` credentials, production URLs
184
- - Debug `puts` in production code paths (PubSub callback is intentional for now)
275
+ - Debug `puts` in production code paths (the native Pub/Sub callback in `lib/valkey/pubsub/pubsub_receiver.rb` must never `puts` or block: it runs on a Rust thread under a borrowed GVL)
185
276
 
186
277
  ## Project Structure (Essential)
187
278
 
@@ -190,38 +281,30 @@ valkey-glide-ruby/
190
281
  ├── lib/valkey.rb
191
282
  ├── lib/valkey/
192
283
  │ ├── bindings.rb
193
- │ ├── libglide_ffi.{so,dylib}
194
- │ ├── commands/*.rb
284
+ │ ├── native/{arch}-{os}/libglide_ffi.{so,dylib} # bundled per-platform lib (packaged during CD)
285
+ │ ├── pubsub/ # Pub/Sub message/state types and internal receiver
286
+ │ ├── commands.rb # requires + includes all command modules
287
+ │ ├── commands/*.rb # 20 command-family modules
195
288
  │ ├── opentelemetry.rb
196
289
  │ ├── pipeline.rb
197
290
  │ ├── request_type.rb
198
291
  │ └── response_type.rb
199
- ├── test/valkey/ # standalone tests
200
- ├── test/cluster/ # cluster tests
292
+ ├── test/unit/ # server-free unit tests
293
+ ├── test/integration/
294
+ │ ├── standalone/ # standalone tests
295
+ │ ├── cluster/ # cluster tests
296
+ │ └── valkey/ # shared valkey-glide-specific test modules
201
297
  ├── test/lint/ # shared lint
202
298
  ├── valkey.gemspec
203
299
  ├── Rakefile
204
300
  └── .github/workflows/ci.yml
205
301
  ```
206
302
 
207
- ## Quality Gates (Agent Checklist)
208
-
209
- - [ ] `bundle exec rubocop` passes
210
- - [ ] `bundle exec rake test:standalone` passes (with Valkey running)
211
- - [ ] `bundle exec rake test:cluster` passes (if cluster commands touched)
212
- - [ ] New commands have tests in `test/valkey/` and lint coverage where applicable
213
- - [ ] `RequestType` matches glide-core enum
214
- - [ ] No secrets or generated junk committed
215
- - [ ] DCO signoff: `git log --format="%B" -n 1 | grep "Signed-off-by"`
216
- - [ ] Conventional commit format used
217
- - [ ] README / DEVELOPER.md updated if public API or setup changed
218
- - [ ] Native lib rebuilt and copied if FFI/protobuf changed upstream
219
-
220
303
  ## Quick Facts for Reasoners
221
304
 
222
305
  **Package:** `valkey-glide-rb` on RubyGems
223
306
  **API Style:** Synchronous.
224
- **Client:** `Valkey.new` — standalone or `cluster_mode: true`
307
+ **Client:** `Valkey.new`, standalone or `cluster_mode: true`
225
308
  **Key Features:** Pipelining, OpenTelemetry (native), statistics, TLS, URL parsing, cluster routing
226
309
  **Testing:** Minitest + rake tasks; lint suites.
227
310
  **Core repo:** [valkey-glide](https://github.com/valkey-io/valkey-glide) (`ffi/`, `glide-core/`)
@@ -232,9 +315,7 @@ valkey-glide-ruby/
232
315
  - **Getting Started:** [README.md](./README.md)
233
316
  - **Contributing:** [CONTRIBUTING.md](./CONTRIBUTING.md)
234
317
  - **Examples:** [examples/](./examples/)
235
- - **Development Setup:** [DEVELOPER.md](./DEVELOPER.md)
236
318
  - **Claude-specific rules:** [CLAUDE.md](./CLAUDE.md)
237
- - **Command coverage:** [Wiki — implementation status](https://github.com/valkey-io/valkey-glide-ruby/wiki/The-implementation-status-of-the-Valkey-commands)
319
+ - **Command coverage:** [GLIDE supported commands](https://glide.valkey.io/commands/supported-commands/)
238
320
  - **GLIDE docs:** [glide.valkey.io](https://glide.valkey.io/)
239
321
  - **Upstream FFI:** [valkey-glide/ffi](https://github.com/valkey-io/valkey-glide/tree/main/ffi)
240
- - **Other language AGENTS.md:** [valkey-glide/python/AGENTS.md](https://github.com/valkey-io/valkey-glide/blob/main/python/AGENTS.md), [java/AGENTS.md](https://github.com/valkey-io/valkey-glide/blob/main/java/AGENTS.md)
data/CHANGELOG.md CHANGED
@@ -1,17 +1,70 @@
1
1
  # Changelog
2
2
 
3
- ## Pending
3
+ All notable changes to this project are documented in this file.
4
4
 
5
- ### Fixes
5
+ GLIDE Ruby follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
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.
7
+ ## Latest
8
8
 
9
- ### Changes
9
+ ### Added
10
10
 
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
- * 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
- * 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.
11
+ ### Changed
12
+
13
+ ### Removed
14
+
15
+ ### Fixed
16
+
17
+ ## [1.1.0]
18
+
19
+ ### Added
20
+
21
+ - Added the Apache 2.0 project license, project notice, and redis-rb MIT license to distributed gems. ([#411](https://github.com/valkey-io/valkey-glide-ruby/pull/411))
22
+ - Added support for `sismember_if_exists(key, member)` with Valkey 9.2 or later. ([#383](https://github.com/valkey-io/valkey-glide-ruby/pull/383))
23
+ - Added support for `delifeq(key, value)` with Valkey 9.0 or later. ([#382](https://github.com/valkey-io/valkey-glide-ruby/pull/382))
24
+ - Added support for `Valkey::ReadFrom::AZ_AFFINITY_ALL_NODES` to prefer all nodes in the client's availability zone before other nodes. ([#349](https://github.com/valkey-io/valkey-glide-ruby/pull/349))
25
+ - Added support for `hgetdel(key, *fields)` with Valkey 9.1 or later. ([#348](https://github.com/valkey-io/valkey-glide-ruby/pull/348))
26
+ - Added support for IAM authentication through `Valkey::IamAuthConfig`, the `iam_config:` connection option, `refresh_iam_token`, and the ElastiCache and MemoryDB service types. ([#342](https://github.com/valkey-io/valkey-glide-ruby/pull/342))
27
+ - Added support for custom OpenTelemetry resource attributes through `Valkey::OpenTelemetry.init(resource_attributes:)`, including automatic process attributes without replacing values already set in `OTEL_RESOURCE_ATTRIBUTES`. ([#325](https://github.com/valkey-io/valkey-glide-ruby/pull/325))
28
+ - Added support for setting the `CLIENT SETINFO LIB-NAME` value with the `lib_name:` and `client_info_tag:` connection options. ([#246](https://github.com/valkey-io/valkey-glide-ruby/pull/246))
29
+ - Added support for `FT.CREATE`, `FT.DROPINDEX`, `FT.INFO`, `FT.SEARCH`, and `FT.AGGREGATE` through `Valkey::Search` builders, with structured `FT.SEARCH` results. ([#295](https://github.com/valkey-io/valkey-glide-ruby/pull/295))
30
+ - Added support for inline Pub/Sub subscriptions and message reads through `subscribe`, `unsubscribe`, `get_pubsub_message`, and `try_get_pubsub_message`. ([#308](https://github.com/valkey-io/valkey-glide-ruby/pull/308))
31
+ - Added support for pattern subscriptions, nonblocking lazy subscription changes, and callback-based Pub/Sub delivery. ([#316](https://github.com/valkey-io/valkey-glide-ruby/pull/316))
32
+ - Added support for sharded Pub/Sub in cluster mode through `ssubscribe`, `sunsubscribe`, their lazy variants, and `publish(..., sharded: true)`. ([#317](https://github.com/valkey-io/valkey-glide-ruby/pull/317))
33
+ - Added support for inspecting Pub/Sub channels, subscriber counts, and connection subscription state. ([#320](https://github.com/valkey-io/valkey-glide-ruby/pull/320))
34
+ - Added support for queuing Pub/Sub commands in `pipelined` and `multi`. ([#329](https://github.com/valkey-io/valkey-glide-ruby/pull/329))
35
+ - Added support for Alpine Linux on x86_64 and aarch64. ([#143](https://github.com/valkey-io/valkey-glide-ruby/pull/143))
36
+ - Added support for propagating W3C trace context into command and pipeline spans through `Valkey::OpenTelemetry.set_parent_span_context_provider` and `parent_span_context_provider:`. ([#161](https://github.com/valkey-io/valkey-glide-ruby/pull/161))
37
+ - Added Sigstore build-provenance attestations to gems published on RubyGems.org. ([#338](https://github.com/valkey-io/valkey-glide-ruby/pull/338))
38
+
39
+ ### Changed
40
+
41
+ - Prevented `client(:subcommand)` from invoking private methods, so custom `Valkey` subclasses must make any dispatched `client_*` handlers public. ([#246](https://github.com/valkey-io/valkey-glide-ruby/pull/246))
42
+ - Trimmed whitespace from string `client_az` values and rejected blank values when an availability-zone affinity strategy is selected. ([#349](https://github.com/valkey-io/valkey-glide-ruby/pull/349))
43
+ - Changed `eval`, `evalsha`, their read-only variants, and `script_load` to execute server commands, accept integer key counts, and report missing scripts instead of reloading them automatically. ([#227](https://github.com/valkey-io/valkey-glide-ruby/pull/227))
44
+ - Changed the default RESP protocol to RESP3, in line with other GLIDE clients. ([#331](https://github.com/valkey-io/valkey-glide-ruby/pull/331))
45
+
46
+ ### Removed
47
+
48
+ - Removed raw-token options, `ft(:subcommand)`, unsupported `FT.*` wrappers, and the `dd:` option from the Search API; use `call` for raw Search commands. ([#295](https://github.com/valkey-io/valkey-glide-ruby/pull/295))
49
+
50
+ ### Fixed
51
+
52
+ - Required TLS for IAM authentication, rejecting IAM configurations without TLS during client creation. ([#397](https://github.com/valkey-io/valkey-glide-ruby/pull/397))
53
+ - Rejected `cluster_mode: true` without an explicit seed node instead of connecting to the standalone default. ([#344](https://github.com/valkey-io/valkey-glide-ruby/pull/344))
54
+ - Treated empty `lib_name:` and `client_info_tag:` values as unset so they no longer produce invalid library names. ([#246](https://github.com/valkey-io/valkey-glide-ruby/pull/246))
55
+ - Placed the `xpending` `idle:` filter in the correct command position and omitted it only when its value is `nil`. ([#300](https://github.com/valkey-io/valkey-glide-ruby/pull/300))
56
+ - Raised `Valkey::InheritedError` instead of terminating the process when a child process uses a client created before `fork()`. ([#302](https://github.com/valkey-io/valkey-glide-ruby/pull/302))
57
+ - Preserved successful pipeline and transaction replies when another queued command fails, added `multi(exception: false)`, distinguished queue-time aborts with `Valkey::ExecAbortError`, and retained float and error values in transaction results. ([#299](https://github.com/valkey-io/valkey-glide-ruby/pull/299))
58
+ - Restored `blpop`, `brpop`, `blmove`, `rpoplpush`, and `brpoplpush`, with the deprecated pop-push methods delegated to `lmove` and `blmove`. ([#220](https://github.com/valkey-io/valkey-glide-ruby/pull/220))
59
+ - Released the Ruby global VM lock while creating a client so other Ruby threads can continue running during connection setup. ([#316](https://github.com/valkey-io/valkey-glide-ruby/pull/316))
60
+ - Sized FFI argument-length buffers for the platform's `unsigned long` width to prevent memory corruption on platforms where it is four bytes. ([#338](https://github.com/valkey-io/valkey-glide-ruby/pull/338))
61
+ - Built Linux release binaries against glibc 2.17 for compatibility with supported Linux distributions. ([#232](https://github.com/valkey-io/valkey-glide-ruby/pull/232))
62
+
63
+ ## [1.0.0] - 2026-08-12
64
+
65
+ ### Added
66
+
67
+ - Published the first general availability release.
68
+
69
+ [1.1.0]: https://github.com/valkey-io/valkey-glide-ruby/releases/tag/v1.1.0
70
+ [1.0.0]: https://github.com/valkey-io/valkey-glide-ruby/releases/tag/v1.0.0