genstore

package
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Aug 23, 2025 License: Apache-2.0 Imports: 6 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type GenStore

type GenStore interface {
	// Snapshot returns the current generation; missing => 0.
	Snapshot(ctx context.Context, storageKey string) (uint64, error)
	// SnapshotMany returns gens for many keys; missing => 0.
	SnapshotMany(ctx context.Context, storageKeys []string) (map[string]uint64, error)
	// Bump atomically increments and returns the new generation.
	Bump(ctx context.Context, storageKey string) (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.

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 in this implementation 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 string) (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 string) (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 []string) (map[string]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, namespace string) *RedisGenStore

NewRedisGenStore creates a Redis-backed generation store without TTL.

func NewRedisGenStoreWithTTL

func NewRedisGenStoreWithTTL(client redis.UniversalClient, namespace string, 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, storageKey string) (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(ctx context.Context) error

Close closes the underlying Redis client.

func (*RedisGenStore) Snapshot

func (s *RedisGenStore) Snapshot(ctx context.Context, storageKey string) (uint64, error)

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

func (*RedisGenStore) SnapshotMany

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

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

Jump to

Keyboard shortcuts

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