kv: add Redis/Valkey driver - #60
Merged
Merged
Conversation
A third kv.Driver backed by any RESP server — Redis, Valkey, or wire-compatible (the `redis` and `valkey` config driver names are aliases for the same implementation). Opt-in per backend; serves the kv block only (other blocks' factories reject it, matching how fs/s3 serve artifact only). Layout: each record is a hash `<prefix>h:<ns>\x1e<key>`; a per-namespace sorted set `<prefix>i:<ns>` indexes live keys so Scan is an ordered ZRANGEBYLEX (byte-ordered, prefix + start_after cursor, consistent with the memory driver's sort and postgres's COLLATE "C") and the item quota is a ZCARD. Expiry is authoritative on a stored expires_at field (read paths filter > now, like postgres) with a native PEXPIRE backstop for memory reclamation; index members orphaned by a reclaimed record are pruned lazily on Scan/Delete and when a quota'd Put reaches the cap (self-healing so the soft quota stays honest). Put (version bump + CAS + quota) and Delete (CAS) run as atomic Lua scripts; MaxItems and tenant qualification flow through unchanged, so per-tenant quotas work here too. - internal/kv/drivers/redis: driver + lex-range unit tests (CI-run) + integration conformance harness (//go:build integration, testcontainers) - config: whitelist redis|valkey; fix the unknown-driver negative test - main: buildKVRegistry redis/valkey case + newKVRedisDriver (dsn/dsn_env, key_prefix) - go.mod: github.com/redis/go-redis/v9, testcontainers redis module - docs: kv Drivers table + config reference backends + example.yaml Verified: full kvtest conformance (all 12 cases incl. Quota, TTL, CAS, Scan cursor, ConcurrentPut) green against a live Redis; go build/vet, go test -race ./..., golangci-lint ./... all clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
7 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #59 (kv quota).
A third
kv.Driverbacked by any RESP server (Redis, Valkey, wire-compatible — theredis/valkeydriver names are aliases). Opt-in per backend; serves the kv block only.ZRANGEBYLEXScan (byte-ordered, prefix +start_aftercursor) andZCARDquota> now, like postgres) + nativePEXPIREbackstop; stale index members pruned lazily on Scan/Delete and when a quota'd Put hits the cap (self-healing)Put(version bump + CAS + quota) andDelete(CAS) as atomic Lua scripts;MaxItems+ tenant qualification flow through unchanged → per-tenant quotas work here toonewKVRedisDriver(dsn/dsn_env, key_prefix); go-redis/v9 dep; CI lex-range unit tests; integration conformance harness; docsVerified: full kvtest conformance (all 12 cases incl. Quota, TTL, CAS, Scan cursor, ConcurrentPut) green against a live Redis.
🤖 Generated with Claude Code