memstore

package
v0.1.0-alpha.13 Latest Latest
Warning

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

Go to latest
Published: Jul 30, 2026 License: MIT Imports: 5 Imported by: 0

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

View Source
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 New

func New(options Options) *Store

New creates a Store with the given bounds.

func (*Store) AcquireLease

func (s *Store) AcquireLease(_ context.Context, key string, ttl time.Duration) (bool, error)

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

func (s *Store) AdoptTagVersion(tag string, version int64)

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

func (s *Store) BumpTag(_ context.Context, tag string) error

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) Bytes

func (s *Store) Bytes() int64

Bytes reports the total size of live entries counted against MaxBytes.

func (*Store) Delete

func (s *Store) Delete(_ context.Context, key string) error

Delete removes key. Deleting a missing key is not an error.

func (*Store) Get

func (s *Store) Get(_ context.Context, key string) (cache.Record, bool, error)

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

func (s *Store) Len() int

Len reports the number of live entries, including any that a subsequent Get would discard as expired or invalidated.

func (*Store) Set

func (s *Store) Set(_ context.Context, key string, record cache.Record, ttl time.Duration) error

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.

func (*Store) TagVersions

func (s *Store) TagVersions(_ context.Context, tags []string) (map[string]int64, error)

TagVersions returns this process's view of each tag's version. Tags never seen report 0.

Jump to

Keyboard shortcuts

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