genstore

package
v1.2.1 Latest Latest
Warning

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

Go to latest
Published: Mar 14, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrNilRedisClient = errors.New("redis genstore: nil client")

Functions

This section is empty.

Types

type CacheKey added in v1.0.0

type CacheKey struct {
	// contains filtered or unexported fields
}

CacheKey is an canonical single-key identity generated by cascache. It is not a logical user key and must be treated as exact bytes.

func NewCacheKey added in v1.0.0

func NewCacheKey(raw string) CacheKey

NewCacheKey constructs a canonical cache identity from its exact bytes. This is mainly for cascache internals, GenStore implementations, and tests. Application code should normally work with logical keys through CAS methods.

func (CacheKey) String added in v1.0.0

func (k CacheKey) String() string

type GenStore

type GenStore interface {
	// Snapshot returns the current generation for a canonical single-key
	// identity; missing => 0.
	Snapshot(ctx context.Context, cacheKey CacheKey) (uint64, error)

	// SnapshotMany returns gens for many canonical single-key identities.
	// Missing keys map to 0 in the returned map under the same CacheKey values.
	SnapshotMany(ctx context.Context, cacheKeys []CacheKey) (map[CacheKey]uint64, error)

	// Bump atomically increments and returns the new generation for a canonical
	// single-key identity.
	Bump(ctx context.Context, cacheKey CacheKey) (uint64, error)

	// Cleanup prunes old metadata if applicable (no-op for Redis).
	Cleanup(retention time.Duration)

	// Close releases resources (no-op ok).
	Close(context.Context) error
}

GenStore abstracts where generations live. Use LocalGenStore (default) for in-process gens, or RedisGenStore for distributed gens.

CacheKey values are opaque canonical identities generated by cascache. Implementations must treat them as exact bytes and must not try to parse, normalize, or reconstruct them from logical user keys.

type LocalGenStore

type LocalGenStore struct {
	// contains filtered or unexported fields
}

LocalGenStore keeps generations in-process (no network I/O). Optionally starts a background cleanup goroutine that periodically prunes keys whose generation hasn't been bumped for at least `retention` duration.

  • Reads take a shared RLock (Snapshot, SnapshotMany).
  • Bumps take an exclusive Lock and are O(1).
  • Cleanup takes an exclusive Lock and scans the map.

Ctx parameters are accepted to satisfy the GenStore interface, but are ignored because all operations are local and non-blocking.

func NewLocalGenStore

func NewLocalGenStore(cleanupInterval, retention time.Duration) *LocalGenStore

NewLocalGenStore constructs a LocalGenStore.

If both cleanupInterval > 0 and retention > 0, a background goroutine is started that calls Cleanup(retention) every cleanupInterval. If either is non-positive, no background cleanup runs and you may call Cleanup manually.

func (*LocalGenStore) Bump

func (s *LocalGenStore) Bump(_ context.Context, k CacheKey) (uint64, error)

Bump atomically increments the generation for key k and updates UpdatedAt. If the key does not exist, it is created with Gen=1.

Returns the new generation value.

func (*LocalGenStore) Cleanup

func (s *LocalGenStore) Cleanup(retention time.Duration)

Cleanup removes keys whose UpdatedAt is older than retention ago.

This bounds memory usage of the in-process map for long-inactive keys. Reads remain correct if a key is cleaned up: Snapshot will report 0 until the next bump recreates the entry.

func (*LocalGenStore) Close

func (s *LocalGenStore) Close(_ context.Context) error

Close stops the optional cleanup goroutine and releases the ticker. Safe to call Close multiple times; subsequent calls are no-ops.

func (*LocalGenStore) Snapshot

func (s *LocalGenStore) Snapshot(_ context.Context, k CacheKey) (uint64, error)

Snapshot returns the current generation for key k.

Returns 0 if the key has never been bumped (i.e., missing in the map). This is safe for CAS semantics: a 0 snapshot simply causes stale writes to be skipped and stale reads to self-heal in the higher-level cache.

func (*LocalGenStore) SnapshotMany

func (s *LocalGenStore) SnapshotMany(_ context.Context, ks []CacheKey) (map[CacheKey]uint64, error)

SnapshotMany returns the current generations for all requested keys.

acquires the read lock once for the entire batch to avoid per-key lock/unlock overhead. Missing keys map to 0 (zero value).

type RedisGenStore

type RedisGenStore struct {
	// contains filtered or unexported fields
}

RedisGenStore shares per-key generations across processes and survives restarts. Optionally, a TTL can be applied to generation keys to prevent unbounded growth. If a generation key expires, readers observe gen=0 and cache entries self-heal.

func NewRedisGenStore

func NewRedisGenStore(client redis.UniversalClient) *RedisGenStore

NewRedisGenStore creates a Redis-backed generation store without TTL.

func NewRedisGenStoreWithOptions added in v0.3.1

func NewRedisGenStoreWithOptions(opts RedisGenStoreOptions) (*RedisGenStore, error)

NewRedisGenStoreWithOptions creates a Redis-backed generation store with explicit lifecycle ownership. CloseClient should be true only when this genstore exclusively owns the client.

func NewRedisGenStoreWithTTL

func NewRedisGenStoreWithTTL(client redis.UniversalClient, ttl time.Duration) *RedisGenStore

NewRedisGenStoreWithTTL creates a Redis-backed generation store with TTL. If ttl <= 0, keys do not expire.

func (*RedisGenStore) Bump

func (s *RedisGenStore) Bump(ctx context.Context, cacheKey CacheKey) (uint64, error)

Bump atomically increments the generation and (optionally) refreshes TTL. When ttl > 0, INCR + EXPIRE are pipelined in a single round-trip and the INCR result is captured from the pipeline (no extra INCR).

func (*RedisGenStore) Cleanup

func (s *RedisGenStore) Cleanup(time.Duration)

Cleanup is not applicable for RedisGenStore (Redis handles expiry if TTL is set).

func (*RedisGenStore) Close

func (s *RedisGenStore) Close(context.Context) error

Close closes the underlying Redis client only when this genstore owns it. Shared clients are left open by default.

func (*RedisGenStore) Snapshot

func (s *RedisGenStore) Snapshot(ctx context.Context, cacheKey CacheKey) (uint64, error)

Snapshot returns the current generation. Missing keys are treated as generation 0.

func (*RedisGenStore) SnapshotMany

func (s *RedisGenStore) SnapshotMany(ctx context.Context, cacheKeys []CacheKey) (map[CacheKey]uint64, error)

SnapshotMany returns generations for multiple keys. Missing keys map to 0.

type RedisGenStoreOptions added in v0.3.1

type RedisGenStoreOptions struct {
	Client      redis.UniversalClient
	TTL         time.Duration
	CloseClient bool
}

Jump to

Keyboard shortcuts

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