redisstore

package
v0.2.22 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 18, 2026 License: MPL-2.0 Imports: 9 Imported by: 0

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

View Source
const StoreName = "redis"

StoreName is the valkeyrie registry name — kept as "redis" so the fleet's TXCO_KVSTORE=redis selects this store unchanged.

Variables

View Source
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

type Config struct {
	TLS      *tls.Config
	Username string
	Password string
	DB       int
}

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

func New(_ context.Context, endpoints []string, options *Config) (*Store, error)

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

func (r *Store) AtomicDelete(ctx context.Context, key string, previous *store.KVPair) (bool, error)

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) Close

func (r *Store) Close() error

Close the store connection.

func (*Store) Delete

func (r *Store) Delete(ctx context.Context, key string) error

Delete the value at the specified key.

func (*Store) DeleteTree

func (r *Store) DeleteTree(ctx context.Context, directory string) error

DeleteTree deletes all keys under a given prefix. Not atomic: the SCAN and the DEL are separate commands (upstream behavior, unchanged).

func (*Store) Exists

func (r *Store) Exists(ctx context.Context, key string, _ *store.ReadOptions) (bool, error)

Exists verifies whether a key exists in the store.

func (*Store) Get

func (r *Store) Get(ctx context.Context, key string, _ *store.ReadOptions) (*store.KVPair, error)

Get a value given its key.

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).

func (*Store) NewLock

func (r *Store) NewLock(_ context.Context, _ string, _ *store.LockOptions) (store.Locker, error)

NewLock is not supported (the chassis KV never takes distributed locks).

func (*Store) Put

func (r *Store) Put(ctx context.Context, key string, value []byte, opts *store.WriteOptions) error

Put a value at the specified key. opts.TTL sets a native redis expiry.

func (*Store) Watch

func (r *Store) Watch(_ context.Context, _ string, _ *store.ReadOptions) (<-chan *store.KVPair, error)

Watch is not supported (the chassis KV never watches keys).

func (*Store) WatchTree

func (r *Store) WatchTree(_ context.Context, _ string, _ *store.ReadOptions) (<-chan []*store.KVPair, error)

WatchTree is not supported (the chassis KV never watches keys).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL