LLM.md is the source and stays the source; CLAUDE.md is a symlink to it, so there is
one file and it cannot drift from itself. What changes is that the link is committed
rather than left for each checkout to recreate.
Left untracked, the doc was conditional on a step outside the repo: a fresh clone had
no CLAUDE.md, nothing loaded LLM.md, and an agent worked here having never read what
this repo already explains. Most of the estate already tracks theirs; this is the rest
agreeing with them.
The package is kv, the scheme is kv://, and the org holds one repo per language
or concern. Records the two floors a consumer has to clear: v9.21.1 for the
module path, v9.22.0 for the package rename.
Renaming the package to `kv` collided with local variables already named `kv`.
In two table tests the local shadowed the package, so a type reference stopped
resolving:
kv, err := client.HRandFieldWithValues(...) // local named kv
Equal([]kv.KeyValue{...}) // resolves to the VARIABLE
-> kv.KeyValue is not a type
The locals hold slices, so they are now `kvs`. Only these two mattered: the
other locals named `kv` live inside package kv itself, where the package
qualifier is never used, so they shadow nothing.
Also renames the last two files that still carried the old vocabulary in their
NAMES rather than their contents: redis.go -> kv.go, redis_test.go -> kv_test.go.
`go vet ./...` now compiles the whole tree including tests.
Last of our own naming to move. The error-code fixture in the wrapping test (and
the README example that mirrors it) still said REDIS_ERROR.
What intentionally remains, and why:
RediSearch — names a specific external module that the FT.* commands map to.
It is an address, not our vocabulary.
StoreDist — matches a case-insensitive search for "redis" by accident
(sto-reDis-t). Not the word.
RELEASE-NOTES.md — a changelog of what upstream shipped. Rewriting history to
pretend it used our names would make it wrong.
We do not use Redis. The client was a go-redis fork and still said so
everywhere: `package redis`, `redis.NewClient`, `redis://`, `extra/redisotel`.
Consumers wrote `redis.Client` against a Valkey-backed store called KV.
package redis -> package kv (93 decls)
redis.X -> kv.X (2,794 call sites)
"redis: …" errors -> "kv: …" (206)
extra/redis{otel,cmd,prometheus,census} -> extra/kv{otel,cmd,prometheus,census}
redis:// , rediss:// -> kv:// , kvs:// (ParseURL)
Redis*/*Redis* idents -> KV*/*KV*
REDIS_VERSION, REDIS_ENDPOINTS_CONFIG_PATH -> KV_*
I previously argued this rename was unsafe because much of it was "wire
contract". That was wrong, and the categorisation shows why: RESP command names
are GET/SET/HSET — they never contain the word. Of 5,771 occurrences only two
kinds were server-visible at all: the ParseURL scheme (we choose what we pass;
our configs already use kv://) and the CLIENT SETINFO lib-name label, which the
server merely records. Nothing here changes a byte of protocol.
Two things deliberately keep the old spelling:
RediSearch — names a specific external module the FT.* commands map to.
StoreDist — contains the letters by accident (sto-reDis-t), not the word.
Breaking for consumers by design: every import site must move redis.X -> kv.X.
Minor bump, never a major — this module stays v9 forever.
KV lives in its own org now, like hanzokms / hanzos3 / hanzo-ds. The repo moved
hanzoai/kv-go -> hanzokv/go, so the module path follows: a Go module path must
match where the repo actually is, or the proxy cannot resolve it.
The name is `go`, not `kv-go`, following the hanzo-ds convention — that org
holds go, mock, native, sqlbuilder, sqlparser, each named for its language or
concern with the ORG supplying the product noun. Repeating "kv" inside a repo
that already lives under hanzokv is the compound-word habit we are dropping.
349 occurrences across 188 files: the root module, all four extra/* modules,
every example module, imports throughout the tree, and the docs. Builds clean.
The package is still `package redis` and the extra dirs are still named
redis*. That rename is deliberately NOT bundled here: it is 5,771 occurrences,
it breaks all 11 consumers at once, and a large share are WIRE CONTRACTS rather
than branding — the redis:// scheme parser, the "redis: nil" error string, RESP
command names. Renaming those breaks protocol compatibility with the Valkey
server. It needs the same our-vocabulary-vs-the-wire split the argo sweep used,
as its own change.
GitHub keeps the old path redirecting, and versions already published under
github.com/hanzoai/kv-go/v9 stay resolvable, so nothing breaks the moment this
lands. Consumers move on their own schedule.
All four extra modules pinned github.com/hanzoai/kv-go/v9 at v9.18.0-beta.2
while the core is published at v9.21.0. The relative `replace` directives mean
local builds resolve the core from ../.. and never exercise that requirement,
so the stale beta pin is invisible until the moment these modules are published
— at which point consumers would resolve a beta.
Source-only change: no tags are pushed here. The extras are still unpublished
(no pushed tags for extra/*/v9), which is why o11y cannot yet swap
pkg/cache/rediscache off upstream go-redis — it imports redisotel, and our
equivalent has no consumable version.
Update module path from github.com/redis/go-redis/v9 to
github.com/hanzoai/kv-go/v9 for use as the Hanzo KV Go SDK.
- Update go.mod module declaration
- Update all Go imports across 260 files
- Update all submodule go.mod files (extra/*, example/*, internal/customvet)
* fix(rediscmd): include space in simple byte range (#3204)
* add space test
---------
Co-authored-by: fumiyanokesinn <[email protected]>
Co-authored-by: Nedyalko Dyakov <[email protected]>
As of Go 1.20, this is the idiomatic way to convert from Bytes to
String and vice-versa.
This updates `go.mod` to 1.20, builds have already been running on
1.23.x and 1.24.x since #3274.
Co-authored-by: Nedyalko Dyakov <[email protected]>
* chore(go): update go version to 1.21
* chore(aggregators): make aggregators work with 1.21
* fix doctests
* address copilot comments
* use atomic bool for logic and/or aggregators
* Update .github/workflows/build.yml
Co-authored-by: ccoVeille <[email protected]>
* use stable/oldstable, 1.23 and 1.21
* fix versions in README
* add oldstable in wordlist
---------
Co-authored-by: ccoVeille <[email protected]>
* test: reduce flakiness in e2e tests
- Increase traffic analysis duration from 30s to 60s in endpoint types test to allow sufficient time for push notification analysis
- Fix TLS config test function name by replacing Cyrillic 'Т' with ASCII 'T' to ensure proper test discovery
* test: disable TLS configurations test
Skip TLS configurations test due to missing TLS environment in test setup
* Remove metrics with empty data
Because empty data cannot be considered an error.
* redis.Nil uses a separate state.
Better differentiation between values, null values, and errors.
There is no Stringer on the channel struct, so using %s causes an error.
Using %v to print the default representation instead.
Co-authored-by: Nedyalko Dyakov <[email protected]>
* fix(pool): prevent double freeTurn in queuedNewConn
This commit fixes a critical race condition where freeTurn() could be
called twice in the connection pool's queuedNewConn flow, causing turn
counter inconsistency.
Problem:
- When a new connection creation failed in queuedNewConn, both the
defer handler and the dialing goroutine could call freeTurn()
- This led to turn counter underflow and queue length inconsistency
Solution:
- Modified putIdleConn to return a boolean indicating whether the
caller needs to call freeTurn()
- Returns true: connection was put back to pool, caller must free turn
- Returns false: connection was delivered to a waiting request,
turn will be freed by the receiving goroutine
- Updated queuedNewConn to only call freeTurn() when putIdleConn
returns true
- Improved error handling flow in the dialing goroutine
Changes:
- putIdleConn now returns bool instead of void
- Added comprehensive documentation for putIdleConn behavior
- Refactored error handling in queuedNewConn goroutine
- Updated test cases to reflect correct turn state expectations
This ensures each turn is freed exactly once, preventing resource
leaks and maintaining correct queue state.
* fix: sync double freeturn bug fix and context calculation from upstream
Synced from https://github.com/redis/go-redis/tree/ndyakov/freeturn-fix
Changes include:
- Add comprehensive tests for double freeTurn bug detection
- Improve context timeout calculation using min(remaining time, DialTimeout)
- Prevent goroutines from waiting longer than necessary
Co-authored-by: Nedyalko Dyakov <[email protected]>
Co-authored-by: Copilot <[email protected]>
---------
Co-authored-by: Nedyalko Dyakov <[email protected]>
Co-authored-by: Nedyalko Dyakov <[email protected]>
Co-authored-by: Copilot <[email protected]>