Files
o11y/pkg/cache/rediscache/provider.go
zeekay bf8f46d0fa refactor(cache): bump kv-go to v9.22.0 and rename qualifier redis -> kv
hanzokv/go v9.22.0 renames its Go package from `redis` to `kv`, and its
companion modules were renamed too. Import paths that moved:

  extra/redisotel/v9 -> extra/kvotel/v9  (pkg redisotel -> kvotel)
  extra/rediscmd/v9  -> extra/kvcmd/v9   (indirect)

hanzokv/mock v9.2.2 follows suit: package redismock -> kvmock.

rediscache/provider.go imported both unaliased, so the qualifiers changed
along with the paths. go/v9 is now aliased `kv` explicitly, since the
package name is not derivable from its import path.

Deliberately NOT renamed:
- the pkg/cache/rediscache directory. This fork re-syncs pkg/ and cmd/
  wholesale from upstream o11y main, so renaming a directory buys a
  permanent conflict on every future re-sync for zero functional gain.
- the provider selector factory.MustNewName("redis") and the config key
  mapstructure:"redis". Both are operator config surface, matching the
  existing convention that kept the "clickhouse" selector value.

go mod tidy was NOT run: this repo's go.mod is paired with the ci.yaml
cloud pin and tidy resolves against whatever ../cloud is checked out.
Used go mod edit + go mod download instead, so go.sum keeps some inert
entries for the old module paths.

Verified: go build ./... exit 0, go vet ./pkg/cache/... exit 0, and
pkg/cache TestSet passes against the renamed kvmock.
2026-07-26 08:50:04 -07:00

83 lines
2.6 KiB
Go

package rediscache
import (
"context"
"fmt"
"log/slog"
"strings"
"time"
"github.com/hanzokv/go/extra/kvotel/v9"
kv "github.com/hanzokv/go/v9"
"github.com/hanzoai/o11y/pkg/cache"
"github.com/hanzoai/o11y/pkg/errors"
"github.com/hanzoai/o11y/pkg/factory"
"github.com/hanzoai/o11y/pkg/types/cachetypes"
"github.com/hanzoai/o11y/pkg/valuer"
)
type provider struct {
client *kv.Client
settings factory.ScopedProviderSettings
}
func NewFactory() factory.ProviderFactory[cache.Cache, cache.Config] {
return factory.NewProviderFactory(factory.MustNewName("redis"), New)
}
func New(ctx context.Context, providerSettings factory.ProviderSettings, config cache.Config) (cache.Cache, error) {
settings := factory.NewScopedProviderSettings(providerSettings, "github.com/hanzoai/o11y/pkg/cache/rediscache")
client := kv.NewClient(&kv.Options{
Addr: strings.Join([]string{config.Redis.Host, fmt.Sprint(config.Redis.Port)}, ":"),
Password: config.Redis.Password,
DB: config.Redis.DB,
})
if err := client.Ping(ctx).Err(); err != nil {
return nil, err
}
if err := kvotel.InstrumentTracing(client, kvotel.WithTracerProvider(providerSettings.TracerProvider), kvotel.WithDBStatement(true)); err != nil {
return nil, err
}
if err := kvotel.InstrumentMetrics(client, kvotel.WithMeterProvider(providerSettings.MeterProvider)); err != nil {
return nil, err
}
return &provider{client: client, settings: settings}, nil
}
func (c *provider) Set(ctx context.Context, orgID valuer.UUID, cacheKey string, data cachetypes.Cacheable, ttl time.Duration) error {
return c.client.Set(ctx, strings.Join([]string{orgID.StringValue(), cacheKey}, "::"), data, ttl).Err()
}
func (c *provider) Get(ctx context.Context, orgID valuer.UUID, cacheKey string, dest cachetypes.Cacheable) error {
err := c.client.Get(ctx, strings.Join([]string{orgID.StringValue(), cacheKey}, "::")).Scan(dest)
if err != nil {
if errors.Is(err, kv.Nil) {
return errors.Newf(errors.TypeNotFound, errors.CodeNotFound, "key miss")
}
return err
}
return nil
}
func (c *provider) Delete(ctx context.Context, orgID valuer.UUID, cacheKey string) {
c.DeleteMany(ctx, orgID, []string{cacheKey})
}
func (c *provider) DeleteMany(ctx context.Context, orgID valuer.UUID, cacheKeys []string) {
updatedCacheKeys := []string{}
for _, cacheKey := range cacheKeys {
updatedCacheKeys = append(updatedCacheKeys, strings.Join([]string{orgID.StringValue(), cacheKey}, "::"))
}
if err := c.client.Del(ctx, updatedCacheKeys...).Err(); err != nil {
c.settings.Logger().ErrorContext(ctx, "error deleting cache keys", slog.Any("cache_keys", cacheKeys), errors.Attr(err))
}
}