Documentation
¶
Index ¶
- type GenStore
- type LocalGenStore
- func (s *LocalGenStore) Bump(_ context.Context, k string) (uint64, error)
- func (s *LocalGenStore) Cleanup(retention time.Duration)
- func (s *LocalGenStore) Close(_ context.Context) error
- func (s *LocalGenStore) Snapshot(_ context.Context, k string) (uint64, error)
- func (s *LocalGenStore) SnapshotMany(_ context.Context, ks []string) (map[string]uint64, error)
- type RedisGenStore
- func (s *RedisGenStore) Bump(ctx context.Context, storageKey string) (uint64, error)
- func (s *RedisGenStore) Cleanup(time.Duration)
- func (s *RedisGenStore) Close(ctx context.Context) error
- func (s *RedisGenStore) Snapshot(ctx context.Context, storageKey string) (uint64, error)
- func (s *RedisGenStore) SnapshotMany(ctx context.Context, storageKeys []string) (map[string]uint64, error)
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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.