Documentation
¶
Overview ¶
Package memstore implements GoBeyond's in-process L1 cache tier: a bounded TTL + LRU byte store with synchronous writes.
L1 is deliberately not a TTL-only cache. Every Get re-checks the tag versions an entry was built under, and every tag bump synchronously drops the entries it invalidates, so an entry can never outlive its data just because its TTL has not elapsed (Locked decision 13). The store's own TTL bound exists for the case the version check cannot help with: a tag bumped on another instance whose pub/sub broadcast this process never received. Keeping that bound short bounds how long a lost broadcast can matter.
Index ¶
- Constants
- type Options
- type Store
- func (s *Store) AcquireLease(_ context.Context, key string, ttl time.Duration) (bool, error)
- func (s *Store) AdoptTagVersion(tag string, version int64)
- func (s *Store) BumpTag(_ context.Context, tag string) error
- func (s *Store) Bytes() int64
- func (s *Store) Delete(_ context.Context, key string) error
- func (s *Store) Get(_ context.Context, key string) (cache.Record, bool, error)
- func (s *Store) Len() int
- func (s *Store) Set(_ context.Context, key string, record cache.Record, ttl time.Duration) error
- func (s *Store) TagVersions(_ context.Context, tags []string) (map[string]int64, error)
Constants ¶
const ( DefaultMaxEntries = 2048 DefaultMaxBytes = 32 << 20 DefaultMaxTTL = 60 * time.Second )
Default bounds. They are intentionally modest: L1 fronts a shared L2 and a cheap origin recompute, so an oversized in-process cache mostly buys resident memory and longer windows for cross-instance staleness.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Options ¶
type Options struct {
// MaxEntries bounds the number of live entries; the least recently used
// entry is evicted once the bound is exceeded.
MaxEntries int
// MaxBytes bounds the total size of live entries by the same LRU rule. A
// single record larger than the bound is never stored.
MaxBytes int64
// MaxTTL clamps every requested TTL. It is the only thing bounding how
// long this process can serve an entry invalidated elsewhere, so it should
// stay short whenever an L2 is in play.
MaxTTL time.Duration
// Clock overrides time.Now, for tests.
Clock func() time.Time
}
Options configures a Store. The zero value is valid and yields the defaults above.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store is a bounded in-process cache.Store. It is safe for concurrent use.
func (*Store) AcquireLease ¶
AcquireLease grants key's lease for ttl when no unexpired lease is held. Leases are process-local, which is exactly enough when this store is the only tier; with an L2 present the distributed leaser takes precedence.
func (*Store) AdoptTagVersion ¶
AdoptTagVersion applies a tag version learned out of band - from an L2 broadcast or from an entry another instance wrote - and drops the entries it invalidates. Versions only move forward: an older value is ignored.
func (*Store) BumpTag ¶
BumpTag increments a tag's version and synchronously drops every entry built under an older one, so an action that revalidates a tag can return knowing this process will not serve the invalidated entries again.
func (*Store) Get ¶
Get returns the record stored under key, dropping it instead when it has expired or when one of the tags it was built under has since been bumped. The returned Value slice is shared with the store and must not be mutated.
func (*Store) Len ¶
Len reports the number of live entries, including any that a subsequent Get would discard as expired or invalidated.
func (*Store) Set ¶
Set stores record under key for at most ttl, clamped to the configured MaxTTL, and reports ErrStaleWrite when one of the record's tags was bumped while the value was being computed. A record larger than MaxBytes is silently not stored: refusing it keeps the bound honest, and the caller already has the value it was going to cache.