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