Files
goclaw/internal/cache/redis_client.go
T
viettranx 0d3230b2bf feat(cache): add build-tag-gated Redis cache backend
Add optional Redis cache support via `go build -tags redis`, following
the same paired-stub pattern as OTel and Tailscale. The Cache[V] interface
is unchanged; Redis and in-memory implementations are injected at startup
without altering usage logic.

- Add RedisCache[V] implementation with JSON serialization, fail-open on errors
- Add gateway_redis.go / gateway_redis_noop.go paired wiring files
- Refactor GroupWriterCache and ContextFileInterceptor to accept injected caches
- Add GOCLAW_REDIS_DSN env var, docker-compose.redis.yml overlay
- Update Dockerfile and GitHub Actions with ENABLE_REDIS build arg
- Add Redis variant to CI matrix (5 variants: latest, otel, tsnet, redis, full)
2026-03-07 19:27:24 +07:00

36 lines
821 B
Go

//go:build redis
package cache
import (
"context"
"fmt"
"time"
"github.com/redis/go-redis/v9"
)
// NewRedisClient creates a Redis client from a DSN (e.g. "redis://localhost:6379/0")
// and verifies connectivity with a PING.
func NewRedisClient(dsn string) (*redis.Client, error) {
opts, err := redis.ParseURL(dsn)
if err != nil {
return nil, fmt.Errorf("redis: invalid DSN: %w", err)
}
opts.PoolSize = 10
opts.MinIdleConns = 2
opts.DialTimeout = 5 * time.Second
opts.ReadTimeout = 3 * time.Second
opts.WriteTimeout = 3 * time.Second
client := redis.NewClient(opts)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := client.Ping(ctx).Err(); err != nil {
client.Close()
return nil, fmt.Errorf("redis: ping failed: %w", err)
}
return client, nil
}