Documentation
¶
Index ¶
- Variables
- type BatchScripter
- type Entry
- type Mem
- func (m *Mem) Close() error
- func (m *Mem) Del(_ context.Context, key string) error
- func (m *Mem) Expire(_ context.Context, key string, ttl time.Duration) error
- func (m *Mem) Get(_ context.Context, key string) ([]byte, error)
- func (m *Mem) HGet(_ context.Context, key, field string) ([]byte, error)
- func (m *Mem) HSet(_ context.Context, key, field string, value []byte, ttl time.Duration) error
- func (m *Mem) Incr(_ context.Context, key string, delta int64) (int64, error)
- func (m *Mem) Range(_ context.Context, prefix string) ([]Entry, error)
- func (m *Mem) RegisterScript(name string, fn ScriptImpl)
- func (m *Mem) RunScript(ctx context.Context, name, _ string, keys []string, args ...any) ([]byte, error)
- func (m *Mem) RunScriptBatch(ctx context.Context, calls []ScriptCall) []ScriptResult
- func (m *Mem) Set(_ context.Context, key string, value []byte, ttl time.Duration) error
- func (m *Mem) WithLock(ctx context.Context, keys []string, fn func(context.Context) error) error
- type Redis
- func (r *Redis) Close() error
- func (r *Redis) Del(ctx context.Context, key string) error
- func (r *Redis) Expire(ctx context.Context, key string, ttl time.Duration) error
- func (r *Redis) Get(ctx context.Context, key string) ([]byte, error)
- func (r *Redis) Incr(ctx context.Context, key string, delta int64) (int64, error)
- func (r *Redis) Ping(ctx context.Context) error
- func (r *Redis) Range(ctx context.Context, prefix string) ([]Entry, error)
- func (r *Redis) RunScript(ctx context.Context, name, script string, keys []string, args ...any) ([]byte, error)
- func (r *Redis) RunScriptBatch(ctx context.Context, calls []ScriptCall) []ScriptResult
- func (r *Redis) Set(ctx context.Context, key string, value []byte, ttl time.Duration) error
- func (r *Redis) WithLock(ctx context.Context, keys []string, fn func(context.Context) error) error
- type RedisConfig
- type ScriptCall
- type ScriptImpl
- type ScriptResult
- type Scripter
- type SentinelConfig
- type Store
Constants ¶
This section is empty.
Variables ¶
var ErrNotFound = errors.New("state: key not found")
Functions ¶
This section is empty.
Types ¶
type BatchScripter ¶ added in v0.9.8
type BatchScripter interface {
RunScriptBatch(ctx context.Context, calls []ScriptCall) []ScriptResult
}
BatchScripter is an optional interface implemented by stores that can run several independent scripts in a single network round trip (a Redis pipeline). Consumers type-assert to opt in.
Atomicity: each call is individually atomic on its own Cluster slot; the batch provides NO cross-call atomicity. Keys of DIFFERENT calls may live on different slots (each call's own keys must still share a hash tag). Use it only for independent operations — e.g. committing two rate-limit reservations that live under different hash tags and therefore cannot share one CROSSSLOT-safe script.
Results are positional (one per input call, same order); a per-call failure is carried in ScriptResult.Err rather than aborting the batch.
type Mem ¶
type Mem struct {
// contains filtered or unexported fields
}
Mem is an in-memory Store backed by sync.Map.
func (*Mem) HGet ¶
HGet reads one field of a hash stored as synthetic keys "key\x00field". Returns ErrNotFound when either the hash key or the field is absent.
func (*Mem) HSet ¶
HSet writes one field of a hash stored as synthetic keys "key\x00field". When ttl > 0 the field entry gets that TTL; ttl == 0 preserves existing TTL.
func (*Mem) RegisterScript ¶
func (m *Mem) RegisterScript(name string, fn ScriptImpl)
RegisterScript registers a Go emulator for a named script.
func (*Mem) RunScript ¶
func (m *Mem) RunScript(ctx context.Context, name, _ string, keys []string, args ...any) ([]byte, error)
RunScript looks up the named emulator and invokes it.
func (*Mem) RunScriptBatch ¶ added in v0.9.8
func (m *Mem) RunScriptBatch(ctx context.Context, calls []ScriptCall) []ScriptResult
RunScriptBatch runs each call sequentially. Mem is in-process, so there is no round-trip to batch away; running the emulators in order is semantically identical to a Redis pipeline of independent single-slot scripts.
type Redis ¶
type Redis struct {
// contains filtered or unexported fields
}
Redis implements Store (and Scripter) backed by Redis/Valkey.
func NewRedis ¶
func NewRedis(ctx context.Context, cfg RedisConfig) (*Redis, error)
NewRedis constructs a Redis and pings the server. Precedence: ClusterAddrs > Sentinel > Addr (single-node).
func (*Redis) RunScript ¶
func (r *Redis) RunScript(ctx context.Context, name, script string, keys []string, args ...any) ([]byte, error)
RunScript implements Scripter.
func (*Redis) RunScriptBatch ¶ added in v0.9.8
func (r *Redis) RunScriptBatch(ctx context.Context, calls []ScriptCall) []ScriptResult
RunScriptBatch implements BatchScripter: it issues every call in a single pipeline (one network round trip on single-node; one per involved node on Cluster, dispatched together). Each call is an independent EVALSHA — the batch is NOT a transaction, so a per-call failure does not roll back the others. Keys within one call must share a hash tag; keys ACROSS calls may differ (that is the point — it batches away sequential round trips for operations that cannot share a CROSSSLOT-safe script).
func (*Redis) WithLock ¶
WithLock implements the blocking Store contract over SET NX PX: acquisition is retried with jittered backoff (5-25ms) until it succeeds or ctx is done, matching Mem's block-until-acquired semantics. The all-or-nothing Lua acquire (partial holds are rolled back before returning 0) keeps opposite key orders deadlock-free while polling. Cluster safety: all keys must share the same hash tag, else CROSSSLOT.
type RedisConfig ¶
type RedisConfig struct {
Addr string
Sentinel *SentinelConfig
ClusterAddrs []string // non-empty → Cluster mode (redis.NewClusterClient)
DB int
Password string
PoolSize int
MinIdleConns int
}
RedisConfig configures a Redis store. Exactly one of Addr, Sentinel, or ClusterAddrs should be set. When ClusterAddrs is non-empty, a redis.ClusterClient is used and all multi-key operations (RunScript, WithLock) require keys to share the same hash tag to avoid CROSSSLOT errors.
type ScriptCall ¶ added in v0.9.8
ScriptCall describes one script invocation for a batch.
type ScriptImpl ¶
ScriptImpl is the Go-emulator function registered on MemStore. It receives the store so it can call Get/Set/Incr etc. directly.
type ScriptResult ¶ added in v0.9.8
ScriptResult is the positional result of one ScriptCall in a batch.
type Scripter ¶
type Scripter interface {
RunScript(ctx context.Context, name, script string, keys []string, args ...any) ([]byte, error)
}
ScriptRunner is an optional interface implemented by stores that support named Lua (or equivalent) scripts. Consumers type-assert to opt in.
type SentinelConfig ¶
SentinelConfig configures Sentinel-mode failover.
type Store ¶
type Store interface {
Get(ctx context.Context, key string) ([]byte, error)
Set(ctx context.Context, key string, value []byte, ttl time.Duration) error
// Del removes a key. It is a no-op (no error) when the key does not exist.
Del(ctx context.Context, key string) error
Incr(ctx context.Context, key string, delta int64) (int64, error)
Expire(ctx context.Context, key string, ttl time.Duration) error
Range(ctx context.Context, prefix string) ([]Entry, error)
// WithLock runs fn while holding an advisory lock over all keys.
// BLOCKING contract: under contention the call waits (retrying with
// backoff on distributed backends) until the lock is acquired — every
// contender eventually runs fn, or returns the ctx error if ctx is
// cancelled/expires while waiting. It never returns a "busy" error
// without running fn. Mutual exclusion holds across all keys for the
// duration of fn.
WithLock(ctx context.Context, keys []string, fn func(context.Context) error) error
Close() error
}
Store is the operational-state adapter. M1 ships MemStore; M5 will add a Redis-backed implementation.