Documentation
¶
Overview ¶
Package redisstore is the chassis's redis backend for the op-writable KV (txco://kv/*), registered with valkeyrie under the same "redis" name the fleet's TXCO_KVSTORE env selects.
It is a vendored, slimmed derivative of github.com/kvtools/redis v1.2.0 (Apache License 2.0 — see LICENSE.kvtools-redis in this directory), taken in-tree so the chassis controls the semantics that matter against a managed Redis (Upstash bills per command and every command is a network round trip). Changes from upstream, per Apache-2.0 §4(b):
- SCAN COUNT raised 10 → 1000 (scanCount): a full List previously cost ~total_keys/10 sequential round trips regardless of the prefix asked for, since SCAN walks the whole keyspace and MATCH only filters.
- MGET chunked at mgetChunk keys per call (upstream sent ONE unbounded MGET for the entire listing).
- CAS/CAD lua compares the RAW STORED VALUE, not the KVPair "LastIndex" field. Upstream's registry path stored raw values (RawCodec), which never persists LastIndex — its lua compare was nil==nil, i.e. ALWAYS true when the key existed, so AtomicPut was not actually atomic and concurrent kv Incr/CAS could lose updates. Value-compare restores the contract chassis/kv relies on (and drops the cjson dependency).
- Dropped what the chassis never uses: Sentinel/failover, locks, Watch/WatchTree (stubbed with store.ErrCallNotSupported), the codec indirection (values are stored raw — the chassis wrapper's own JSON envelope — readable as-is in a redis console), and the boot-time `CONFIG SET notify-keyspace-events` (only Watch consumed it; Upstash rejects CONFIG).
- setNX surfaces the underlying redis error instead of folding every failure into ErrKeyExists.
Index ¶
- Constants
- Variables
- type Config
- type Store
- func (r *Store) AtomicDelete(ctx context.Context, key string, previous *store.KVPair) (bool, error)
- func (r *Store) AtomicPut(ctx context.Context, key string, value []byte, previous *store.KVPair, ...) (bool, *store.KVPair, error)
- func (r *Store) Close() error
- func (r *Store) Delete(ctx context.Context, key string) error
- func (r *Store) DeleteTree(ctx context.Context, directory string) error
- func (r *Store) Exists(ctx context.Context, key string, _ *store.ReadOptions) (bool, error)
- func (r *Store) Get(ctx context.Context, key string, _ *store.ReadOptions) (*store.KVPair, error)
- func (r *Store) List(ctx context.Context, directory string, _ *store.ReadOptions) ([]*store.KVPair, error)
- func (r *Store) NewLock(_ context.Context, _ string, _ *store.LockOptions) (store.Locker, error)
- func (r *Store) Put(ctx context.Context, key string, value []byte, opts *store.WriteOptions) error
- func (r *Store) Watch(_ context.Context, _ string, _ *store.ReadOptions) (<-chan *store.KVPair, error)
- func (r *Store) WatchTree(_ context.Context, _ string, _ *store.ReadOptions) (<-chan []*store.KVPair, error)
Constants ¶
const StoreName = "redis"
StoreName is the valkeyrie registry name — kept as "redis" so the fleet's TXCO_KVSTORE=redis selects this store unchanged.
Variables ¶
var ErrMultipleEndpointsUnsupported = errors.New("redis: does not support multiple endpoints")
ErrMultipleEndpointsUnsupported is returned when more than one endpoint is given; the chassis KV always connects to a single redis endpoint.
Functions ¶
This section is empty.
Types ¶
type Config ¶
Config is the store configuration — exactly the fields the chassis sets (see app.redisConfigFromAddr): TLS for rediss://, userinfo, and the numeric database from a redis URL path.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store implements the store.Store interface over a single redis endpoint.
func New ¶
New creates the redis-backed store. ctx is unused (the client dials lazily); it is kept for constructor-signature parity with the registry.
func (*Store) AtomicDelete ¶
AtomicDelete deletes the key only if the stored bytes still equal previous.Value.
func (*Store) AtomicPut ¶
func (r *Store) AtomicPut(ctx context.Context, key string, value []byte, previous *store.KVPair, opts *store.WriteOptions) (bool, *store.KVPair, error)
AtomicPut is an atomic compare-and-swap on a single value. previous == nil means create (fails with ErrKeyExists if the key is already there); otherwise the swap happens only if the stored bytes still equal previous.Value (ErrKeyModified when they don't, ErrKeyNotFound when the key vanished).
func (*Store) DeleteTree ¶
DeleteTree deletes all keys under a given prefix. Not atomic: the SCAN and the DEL are separate commands (upstream behavior, unchanged).
func (*Store) List ¶
func (r *Store) List(ctx context.Context, directory string, _ *store.ReadOptions) ([]*store.KVPair, error)
List the content of a given prefix. Returns store.ErrKeyNotFound when nothing matches (the chassis wrapper maps that to an empty namespace).