Help us shape the future of Go! Take the 2026 Go Developer Survey

cacheatomic

package
v0.5.3 Latest Latest
Warning

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

Go to latest
Published: Nov 3, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package cacheatomic shares expiry, counter and mutation semantics for durable cache adapters. The driver serializes Access and Inspect across processes for the same key; reads observe one record without that lock.

Index

Constants

View Source
const DefaultPruneInterval = time.Minute

DefaultPruneInterval is how often a started adapter reclaims expired records.

View Source
const MaxPrune = 256

MaxPrune bounds the records one prune batch removes. Adapters re-export it.

Variables

This section is empty.

Functions

func CapacityError

func CapacityError(adapter string) error

CapacityError is the shared quota rejection after reclaiming expiry failed.

func NamespacePrefix

func NamespacePrefix(namespace cache.Namespace) (string, error)

NamespacePrefix returns the physical address prefix shared by every plain cache entry of namespace, derived from cache.EntryKey's own address format.

func RunPruner

func RunPruner(ctx context.Context, interval time.Duration, logger *slog.Logger, name string, pass func(context.Context) (PruneResult, error))

RunPruner calls pass every interval until stop closes. A tick repeats full batches (bounded) so a backlog drains without waiting for later ticks. Failures are reported through logger as redacted diagnostics only.

func ValidPruneInterval

func ValidPruneInterval(interval time.Duration) bool

ValidPruneInterval accepts zero (automatic pruning disabled) or 1s to 24h.

func ValidValueLimit

func ValidValueLimit(limit int) bool

Types

type Backend

type Backend struct {
	// contains filtered or unexported fields
}

func New

func New(driver Driver, maxValue int) (*Backend, error)

func (*Backend) Add

func (b *Backend) Add(ctx context.Context, key cache.EntryKey, data []byte, ttl cache.TTL) (bool, error)

func (*Backend) Exists

func (b *Backend) Exists(ctx context.Context, key cache.EntryKey) (bool, error)

Exists validates the stored record without the mutation lock. A corrupt or over-bound record is absent. The observation is not a reservation.

func (*Backend) Expire

func (b *Backend) Expire(ctx context.Context, key cache.EntryKey, ttl cache.TTL) (bool, error)

func (*Backend) Forget

func (b *Backend) Forget(ctx context.Context, key cache.EntryKey) (bool, error)

func (*Backend) Get

func (b *Backend) Get(ctx context.Context, key cache.EntryKey) ([]byte, bool, error)

func (*Backend) Increment

func (b *Backend) Increment(ctx context.Context, key cache.EntryKey, delta int64, ttl cache.TTL) (int64, error)

func (*Backend) Put

func (b *Backend) Put(ctx context.Context, key cache.EntryKey, data []byte, ttl cache.TTL) error

type Change

type Change func(now time.Time, previous *Record) (next *Record, update bool, err error)

Change runs while the driver owns the key's atomic lock. now is the storage authority's time, read after the lock was acquired. previous is nil when the entry is absent or unusable (corrupt, or larger than the current bound); such an entry is still replaced or removed by a write. update=false retains bytes; update=true with nil next deletes. Errors preserve the previous entry. Drivers may run a Change more than once before one attempt succeeds.

type Driver

type Driver interface {
	Read(ctx context.Context, key cache.EntryKey, data bool) (*Record, time.Time, error)
	Access(ctx context.Context, key cache.EntryKey, mode Mode, change Change) error
	Inspect(ctx context.Context, key cache.EntryKey, inspection Inspection) (bool, error)
}

Driver owns storage, locking and the authority clock. Read observes one record without the mutation lock and returns the authority time of that observation; unusable records read as nil. data=false validates the stored record without returning its bytes.

type Inspection

type Inspection func(now, expires time.Time) (replacement *time.Time, live bool, err error)

Inspection runs after the driver acquires its lock and reads the record. It checks current liveness at now and optionally returns a replacement expiry. A nil replacement preserves metadata; false never revives an expired entry.

type Limits

type Limits struct {
	MaxEntries    int
	MaxBytes      int64
	MaxValueBytes int
}

Limits shares the persistent adapter ceilings and defaults. Byte accounting follows each storage representation; both reject before replacing live data.

func DefaultLimits

func DefaultLimits() Limits

func (Limits) Validate

func (l Limits) Validate() error

type Mode

type Mode uint8

Mode selects how much of an existing record a mutation needs.

const (
	// Metadata supplies only the previous record's expiry. Replacement needs
	// nothing else, so drivers skip reading and verifying the old payload.
	Metadata Mode = iota
	// Payload supplies the previous record's verified bytes.
	Payload
)

type PruneResult

type PruneResult struct {
	// Removed counts expired records (and file orphans) deleted by this pass.
	Removed int
	// Corrupt counts unreadable records that were skipped. Reads treat them as
	// misses and writes replace them; they still occupy capacity until then.
	Corrupt int
	// Unrecognized counts foreign files skipped in an owned file-cache root.
	Unrecognized int
	// Entries and Bytes are the stored records counted after removal.
	Entries int64
	Bytes   int64
	// Complete reports that the pass counted all storage. Every pass replaces
	// the adapter's usage estimate; an incomplete one with a lower bound.
	Complete bool
}

PruneResult reports one bounded prune pass.

type Record

type Record struct {
	Data    []byte
	Expires time.Time
}

func (*Record) Live

func (r *Record) Live(now time.Time) bool

type Usage

type Usage struct {
	// contains filtered or unexported fields
}

Usage is a backend-owned estimate of stored records and bytes. Writers apply their own deltas without scanning storage; Reconcile replaces the estimate with a counted snapshot. Other processes' writes become visible only at the next reconciliation, so capacity is approximate between prune passes.

func (*Usage) Add

func (u *Usage) Add(entries, bytes int64)

Add applies one writer's delta, never letting the estimate go negative.

func (*Usage) Counted

func (u *Usage) Counted() bool

Counted reports whether any reconciliation has happened.

func (*Usage) Fits

func (u *Usage) Fits(limits Limits, replaced, size int64) bool

Fits reports whether a write of size bytes fits the limits. replaced is the size of an existing physical record at the same address, or -1 when none.

func (*Usage) Reclaimed

func (u *Usage) Reclaimed(result PruneResult)

Reclaimed releases the claim after an on-demand pass that removed records, so only unproductive passes (a cache full of live data) are rate-limited.

func (*Usage) Reconcile

func (u *Usage) Reconcile(entries, bytes int64)

Reconcile replaces the estimate with a counted snapshot.

func (*Usage) ReconcileDue

func (u *Usage) ReconcileDue() bool

ReconcileDue claims the right to reclaim/recount for a write at capacity. At most one claim succeeds per reconcileGap; others reject from the estimate. Scheduled prune passes do not consume the claim.

func (*Usage) Snapshot

func (u *Usage) Snapshot() (entries, bytes int64)

Snapshot returns the current estimate.

Jump to

Keyboard shortcuts

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