mirror of
https://github.com/hanzokv/go.git
synced 2026-09-24 00:31:51 +00:00
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.
210 lines
4.5 KiB
Go
210 lines
4.5 KiB
Go
package kv
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
|
|
"github.com/hanzokv/go/v9/internal/routing"
|
|
)
|
|
|
|
type (
|
|
module = string
|
|
commandName = string
|
|
)
|
|
|
|
var defaultPolicies = map[module]map[commandName]*routing.CommandPolicy{
|
|
"ft": {
|
|
"create": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
},
|
|
"search": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
Tips: map[string]string{
|
|
routing.ReadOnlyCMD: "",
|
|
},
|
|
},
|
|
"aggregate": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
Tips: map[string]string{
|
|
routing.ReadOnlyCMD: "",
|
|
},
|
|
},
|
|
"dictadd": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
},
|
|
"dictdump": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
Tips: map[string]string{
|
|
routing.ReadOnlyCMD: "",
|
|
},
|
|
},
|
|
"dictdel": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
},
|
|
"suglen": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultHashSlot,
|
|
Tips: map[string]string{
|
|
routing.ReadOnlyCMD: "",
|
|
},
|
|
},
|
|
"cursor": {
|
|
Request: routing.ReqSpecial,
|
|
Response: routing.RespDefaultKeyless,
|
|
Tips: map[string]string{
|
|
routing.ReadOnlyCMD: "",
|
|
},
|
|
},
|
|
"sugadd": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultHashSlot,
|
|
},
|
|
"sugget": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultHashSlot,
|
|
Tips: map[string]string{
|
|
routing.ReadOnlyCMD: "",
|
|
},
|
|
},
|
|
"sugdel": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultHashSlot,
|
|
},
|
|
"spellcheck": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
Tips: map[string]string{
|
|
routing.ReadOnlyCMD: "",
|
|
},
|
|
},
|
|
"explain": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
Tips: map[string]string{
|
|
routing.ReadOnlyCMD: "",
|
|
},
|
|
},
|
|
"explaincli": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
Tips: map[string]string{
|
|
routing.ReadOnlyCMD: "",
|
|
},
|
|
},
|
|
"aliasadd": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
},
|
|
"aliasupdate": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
},
|
|
"aliasdel": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
},
|
|
"info": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
Tips: map[string]string{
|
|
routing.ReadOnlyCMD: "",
|
|
},
|
|
},
|
|
"tagvals": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
Tips: map[string]string{
|
|
routing.ReadOnlyCMD: "",
|
|
},
|
|
},
|
|
"syndump": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
Tips: map[string]string{
|
|
routing.ReadOnlyCMD: "",
|
|
},
|
|
},
|
|
"synupdate": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
},
|
|
"profile": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
Tips: map[string]string{
|
|
routing.ReadOnlyCMD: "",
|
|
},
|
|
},
|
|
"alter": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
},
|
|
"dropindex": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
},
|
|
"drop": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
},
|
|
},
|
|
}
|
|
|
|
type CommandInfoResolveFunc func(ctx context.Context, cmd Cmder) *routing.CommandPolicy
|
|
|
|
type commandInfoResolver struct {
|
|
resolveFunc CommandInfoResolveFunc
|
|
fallBackResolver *commandInfoResolver
|
|
}
|
|
|
|
func NewCommandInfoResolver(resolveFunc CommandInfoResolveFunc) *commandInfoResolver {
|
|
return &commandInfoResolver{
|
|
resolveFunc: resolveFunc,
|
|
}
|
|
}
|
|
|
|
func NewDefaultCommandPolicyResolver() *commandInfoResolver {
|
|
return NewCommandInfoResolver(func(ctx context.Context, cmd Cmder) *routing.CommandPolicy {
|
|
module := "core"
|
|
command := cmd.Name()
|
|
cmdParts := strings.Split(command, ".")
|
|
if len(cmdParts) == 2 {
|
|
module = cmdParts[0]
|
|
command = cmdParts[1]
|
|
}
|
|
|
|
if policy, ok := defaultPolicies[module][command]; ok {
|
|
return policy
|
|
}
|
|
|
|
return nil
|
|
})
|
|
}
|
|
|
|
func (r *commandInfoResolver) GetCommandPolicy(ctx context.Context, cmd Cmder) *routing.CommandPolicy {
|
|
if r.resolveFunc == nil {
|
|
return nil
|
|
}
|
|
|
|
policy := r.resolveFunc(ctx, cmd)
|
|
if policy != nil {
|
|
return policy
|
|
}
|
|
|
|
if r.fallBackResolver != nil {
|
|
return r.fallBackResolver.GetCommandPolicy(ctx, cmd)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (r *commandInfoResolver) SetFallbackResolver(fallbackResolver *commandInfoResolver) {
|
|
r.fallBackResolver = fallbackResolver
|
|
}
|