Skip to content

Add shared redis client package#108

Merged
reyortiz3 merged 1 commit into
mainfrom
add-redis-package
May 18, 2026
Merged

Add shared redis client package#108
reyortiz3 merged 1 commit into
mainfrom
add-redis-package

Conversation

@reyortiz3
Copy link
Copy Markdown
Contributor

Summary

Multiple ToolHive components (session storage, auth server storage in toolhive; the API key store in stacklok-llm-gateway once it migrates off valkey-go) need a Redis client with the same connection-mode topology, TLS handling, and timeout defaults. Today the toolhive repo carries two parallel implementations (pkg/transport/session/redis_config.go and pkg/authserver/storage/redis.go) that have already drifted: only the auth-server copy supports Redis Cluster and asymmetric Sentinel TLS.

This PR introduces a shared redis/ package in toolhive-core so the next step can be a pure migration that removes those duplicates and pulls stacklok-llm-gateway onto the same library.

What's in the package

  • Config, SentinelConfig, TLSConfig — unified configuration types.
  • NewClient(ctx, *Config) (goredis.UniversalClient, error) — single factory covering standalone, Redis Cluster, and Sentinel modes; applies timeout defaults, validates connection-mode topology, and Pings before returning.
  • BuildTLSConfig(*TLSConfig) (*tls.Config, error) — exported for callers that need raw TLS.
  • DefaultDialTimeout, DefaultReadTimeout, DefaultWriteTimeout — tunable defaults.
  • Sentinel TLS uses a per-target dialer so master and sentinel daemons can present different certificate chains (matches the richer auth-server behavior).

Validation is intentionally limited to connection-mode topology. Caller-specific rules (key-prefix conventions, ACL enforcement) remain in the caller — they vary per consumer.

Why now

Without this package the next migration PR has to either change two repos at once or land a near-duplicate in each consumer. Landing the shared layer first means each subsequent consumer migration is small and reviewable in isolation.

Type of change

  • New feature (adds a new package)

Test plan

  • task test — 9 tests, all pass with -race
  • task lint on ./redis/... — 0 issues
  • task license-check — pass
  • task tidy — clean (all modules verified)
  • Coverage on the new package: 90.9% (target ≥70% per CLAUDE.md)
  • Standalone path exercised end-to-end via miniredis
  • Cluster and Sentinel paths verified via type assertion on the returned client
  • TLS dialer plumbing covered for both happy path and PEM-parse error

Notes for reviewers

  • The package imports github.com/redis/go-redis/v9 internally aliased as goredis to avoid collision with the package name. Callers that need to reference goredis.UniversalClient should alias similarly.
  • Cluster mode currently takes a single seed address via Config.Addr. This matches the existing toolhive auth-server implementation. If multi-seed bootstrap becomes a requirement later, Addr can be promoted to Addrs []string additively.
  • NewClient copies the caller's Config before applying defaults, so a single *Config can safely be reused across constructors without surprise mutation.
  • Dependency adds: github.com/redis/go-redis/v9 v9.18.0 (direct), github.com/alicebob/miniredis/v2 v2.37.0 (test). The indirect additions (go-rendezvous, gopher-lua, go.uber.org/atomic) are transitive.
  • This is step 1 of a two-step consolidation. Step 2 will migrate toolhive's pkg/transport/session and pkg/authserver/storage onto this package (and, separately, stacklok-llm-gateway once it switches from valkey-go to go-redis).

🤖 Generated with Claude Code

Introduce redis/ as a shared connection layer so that downstream
projects (toolhive, stacklok-llm-gateway) can stop carrying parallel
copies of Redis config, client construction and TLS plumbing.

Public surface:
  - Config, SentinelConfig, TLSConfig
  - NewClient(ctx, *Config) -> goredis.UniversalClient
  - BuildTLSConfig(*TLSConfig) -> *tls.Config
  - DefaultDialTimeout / ReadTimeout / WriteTimeout

Supports standalone, Redis Cluster, and Sentinel modes through a
single factory. Sentinel mode supports asymmetric TLS for master
vs sentinel daemons via a per-target dialer. Validation covers
connection-mode topology only; caller-specific rules (key prefix
conventions, ACL requirements) remain in the caller.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@reyortiz3 reyortiz3 force-pushed the add-redis-package branch from 2ae15af to 1c877d8 Compare May 18, 2026 18:14
@reyortiz3 reyortiz3 merged commit 61581b0 into main May 18, 2026
5 checks passed
@reyortiz3 reyortiz3 deleted the add-redis-package branch May 18, 2026 18:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants