Documentation
¶
Overview ¶
Package cache provides typed, backend-independent cache semantics.
Cache distinguishes fresh Hit, absent/negative Miss, Stale and errors. Backend records own retained payload bytes; generic K and V are not deep copied. A published found load shares the loader's original V with its waiters, so mutable values require application ownership or an explicitly copying codec/loader.
Construct with New and a validated NewKeySpace. Dependencies are retained, must be concurrency-safe, and must bound their own work. Only loader and observer notification panics are isolated; other callbacks are trusted. Observers run synchronously, and some publication callbacks run under a per-flight mutation lock. Do not re-enter that protected boundary.
Caller cancellation detaches one load waiter. Load work uses a separate cache-owned context; Shutdown cancels and joins it within the caller's bound, without closing a backend/client or joining unrelated foreground calls. Incomplete shutdown is not proof that admitted external side effects stopped.
Index ¶
- Constants
- Variables
- type Backend
- type BulkResult
- type Cache
- func (c *Cache[K, V]) Add(ctx context.Context, logical K, value V) (bool, error)
- func (c *Cache[K, V]) Close() error
- func (c *Cache[K, V]) Delete(ctx context.Context, logical K) (err error)
- func (c *Cache[K, V]) DeleteMany(ctx context.Context, keys []K) ([]MutationResult[K], error)
- func (c *Cache[K, V]) Get(ctx context.Context, logical K) (result Result[V], err error)
- func (c *Cache[K, V]) GetMany(ctx context.Context, keys []K) ([]BulkResult[K, V], error)
- func (c *Cache[K, V]) GetOrLoad(ctx context.Context, logical K, loader Loader[K, V]) (Result[V], error)
- func (c *Cache[K, V]) Replace(ctx context.Context, logical K, value V) (bool, error)
- func (c *Cache[K, V]) Set(ctx context.Context, logical K, value V) error
- func (c *Cache[K, V]) SetIfOwned(ctx context.Context, logical K, value V, guard OwnershipGuard) error
- func (c *Cache[K, V]) SetMany(ctx context.Context, entries []Entry[K, V]) ([]MutationResult[K], error)
- func (c *Cache[K, V]) SetNegativeIfOwned(ctx context.Context, logical K, guard OwnershipGuard) error
- func (c *Cache[K, V]) SetWithExpiry(ctx context.Context, logical K, value V, expiry Expiry) error
- func (c *Cache[K, V]) Shutdown(ctx context.Context) error
- type Clock
- type Codec
- type Condition
- type Config
- type Entry
- type Error
- type ErrorKind
- type Event
- type Expiry
- type JSONCodec
- type JitterSource
- type KeyEncoder
- type KeySpace
- type LoadPolicy
- type LoadResult
- type Loader
- type MutationResult
- type Observer
- type Operation
- type Outcome
- type OwnershipBackend
- type OwnershipGuard
- type RandomJitter
- type Record
- type Result
- type State
- type StringKeyEncoder
- type SystemClock
- type TTLPolicy
Examples ¶
Constants ¶
const MaxLoadFlights = 1 << 16
MaxLoadFlights bounds configured loader concurrency and retained flight work.
Variables ¶
var ( // ErrMiss identifies an explicit cache miss where an error value is needed. ErrMiss = errors.New("cache miss") // ErrBackend identifies a storage or transport failure. ErrBackend = errors.New("cache backend error") // ErrDecode identifies malformed serialized data. ErrDecode = errors.New("cache decode error") // ErrSchemaMismatch identifies an incompatible payload version. ErrSchemaMismatch = errors.New("cache schema mismatch") // ErrInvalidKey identifies invalid key configuration or encoding. ErrInvalidKey = errors.New("invalid cache key") // ErrKeyTooLarge identifies a backend key beyond its configured bound. ErrKeyTooLarge = errors.New("cache key too large") // ErrValueTooLarge identifies a payload beyond its configured bound. ErrValueTooLarge = errors.New("cache value too large") // ErrInvalidTTL identifies an invalid or already expired deadline. ErrInvalidTTL = errors.New("invalid cache TTL") // ErrCapacity identifies a record that cannot fit a bounded backend. ErrCapacity = errors.New("cache capacity exceeded") // ErrClosed identifies use after cache or backend shutdown. ErrClosed = errors.New("cache backend closed") // ErrShutdownIncomplete identifies shutdown ending with active loader work. ErrShutdownIncomplete = errors.New("cache shutdown incomplete") // ErrLoader identifies a source loader failure. ErrLoader = errors.New("cache loader error") // ErrLoaderPanic identifies a recovered loader panic. ErrLoaderPanic = errors.New("cache loader panic") // ErrLoadTimeout identifies a loader failure after LoadPolicy.Timeout expired. ErrLoadTimeout = errors.New("cache load timeout") // ErrRecursiveLoad identifies a loader re-entering the same cache. ErrRecursiveLoad = errors.New("recursive cache load") // ErrWaiterLimit identifies excess callers for one active key flight. ErrWaiterLimit = errors.New("cache waiter limit exceeded") // ErrFlightLimit identifies excess distinct-key load or refresh work. ErrFlightLimit = errors.New("cache flight limit exceeded") // ErrInvalidPolicy identifies invalid or contradictory policy options. ErrInvalidPolicy = errors.New("invalid cache policy") // ErrBatchTooLarge identifies a bulk request beyond its configured bound. ErrBatchTooLarge = errors.New("cache batch too large") // ErrInvalidRecord identifies malformed portable backend state. ErrInvalidRecord = errors.New("invalid cache record") // ErrInvalidConfig identifies invalid constructor dependencies or limits. ErrInvalidConfig = errors.New("invalid cache configuration") // ErrOwnershipLost identifies a protected write rejected by its backend. ErrOwnershipLost = errors.New("cache ownership lost") // ErrOwnershipUnsupported identifies a backend without atomic ownership validation. ErrOwnershipUnsupported = errors.New("cache ownership validation unsupported") )
Functions ¶
This section is empty.
Types ¶
type Backend ¶
type Backend interface {
// Get returns a payload copy and explicit presence; failures are not misses.
Get(context.Context, string) (Record, bool, error)
// Set atomically applies condition and owns stored payload bytes on success.
Set(context.Context, string, Record, Condition) (bool, error)
// Delete atomically removes a key and reports presence, not value contents.
Delete(context.Context, string) (bool, error)
}
Backend is the concurrent atomic storage contract implemented by adapters. Presence denotes provider retention, not freshness; Cache.Get separately enforces StaleAt using its clock. Server expiry may differ from that clock. Implementations must honor contexts and copy retained/returned payload bytes. Native clients, retries and shutdown remain provider/caller responsibilities; memory lazy expiration and server TTL precision are not identical.
type BulkResult ¶
type BulkResult[K, V any] struct { // Key is the input key at the corresponding position. Key K // Result is the embedded lookup outcome; inspect Err before using it. Result[V] // Err is this key's failure; the bulk-level error only reports admission failure. Err error }
BulkResult reports one GetMany result without flattening per-key errors.
type Cache ¶
type Cache[K, V any] struct { // contains filtered or unexported fields }
Cache provides concurrent typed cache operations over a retained backend. Use New; a zero/nil Cache is not usable. Dependencies must support concurrent calls, non-nil contexts are required except that Shutdown rejects nil, and callers own mutation of generic keys/values and dependency cleanup.
func New ¶
New validates dependencies, TTL and load bounds and constructs an inert cache. Keys must already come from NewKeySpace; its zero value is not validated here. No goroutine is started until a flight is admitted. Config collaborators are retained by identity; construction does not clone or open backend resources.
func (*Cache[K, V]) Close ¶
Close cancels active loads, rejects new loads, and waits up to five seconds for loader/notification cleanup. It does not close the backend or client.
func (*Cache[K, V]) DeleteMany ¶
func (c *Cache[K, V]) DeleteMany(ctx context.Context, keys []K) ([]MutationResult[K], error)
DeleteMany deletes keys sequentially in input order with per-key failures. There is no transaction or early stop after a failed/canceled item.
func (*Cache[K, V]) Get ¶
Get returns an explicit hit, negative/ordinary miss, or stale result. Freshness is Before(ExpiresAt); StaleAt is exclusive hard expiry. Hard expiry cleanup failures remain errors. Positive Decode ownership comes from Codec. Sliding fresh reads rewrite the record using IfPresent, not record-version compare-and-set, and can race a newer write. Stale/negative reads do not slide.
func (*Cache[K, V]) GetMany ¶
func (c *Cache[K, V]) GetMany(ctx context.Context, keys []K) ([]BulkResult[K, V], error)
GetMany reads keys sequentially in input order without a pipeline/transaction. Admission failure is the top-level error; per-key errors do not stop the loop, even after cancellation. Generic keys/results are not deep copied.
func (*Cache[K, V]) GetOrLoad ¶
func (c *Cache[K, V]) GetOrLoad(ctx context.Context, logical K, loader Loader[K, V]) (Result[V], error)
GetOrLoad returns a cached value or coalesces source work by encoded key. The first admitted flight's loader/key arguments serve every follower. Caller cancellation only detaches that waiter, including the last waiter. All followers of a published found load share its original V, not deep copies. Double checks or superseding mutations can instead return current decoded state. Stale-while-revalidate returns admission errors with stale data; later refresh errors are observed. Stale-if-error returns the original stale data plus error. Recursive calls with the supplied loader context reject the same Cache even for a different key; discarding that context bypasses detection. With InheritValues the admitting caller's values reach the loader; ctx's cancellation and deadline never do.
Example ¶
package main
import (
"context"
"fmt"
"time"
cache "github.com/faustbrian/go-cache/v4"
cachememory "github.com/faustbrian/go-cache/v4/adapters/memory"
)
func main() {
backend, _ := cachememory.New(cachememory.Config{
MaxEntries: 100,
MaxBytes: 1 << 20,
Clock: cache.SystemClock{},
})
keys, _ := cache.NewKeySpace("example", "greeting", 1, cache.StringKeyEncoder{}, 128)
store, _ := cache.New(cache.Config[string, string]{
Backend: backend,
Keys: keys,
Codec: cache.JSONCodec[string]{Version: 1},
TTL: cache.TTLPolicy{TTL: time.Minute},
Clock: cache.SystemClock{},
MaxValue: 1024,
})
defer func() { _ = store.Close() }()
result, err := store.GetOrLoad(context.Background(), "hello",
func(context.Context, string) (cache.LoadResult[string], error) {
return cache.LoadResult[string]{Value: "world", Found: true}, nil
})
fmt.Println(result.State == cache.Hit, result.Value, err)
}
Output: true world <nil>
func (*Cache[K, V]) SetIfOwned ¶
func (c *Cache[K, V]) SetIfOwned( ctx context.Context, logical K, value V, guard OwnershipGuard, ) error
SetIfOwned atomically writes a value only while guard identifies the active backend owner. Ownership loss is reported as ErrOwnershipLost.
func (*Cache[K, V]) SetMany ¶
func (c *Cache[K, V]) SetMany(ctx context.Context, entries []Entry[K, V]) ([]MutationResult[K], error)
SetMany writes entries sequentially in input order and records per-key errors. There is no rollback, transaction or early stop after a failed/canceled item.
func (*Cache[K, V]) SetNegativeIfOwned ¶
func (c *Cache[K, V]) SetNegativeIfOwned( ctx context.Context, logical K, guard OwnershipGuard, ) error
SetNegativeIfOwned atomically writes an explicit negative record only while guard identifies the active backend owner. The configured NegativeTTL must be positive. Ownership loss is reported as ErrOwnershipLost.
func (*Cache[K, V]) SetWithExpiry ¶ added in v4.1.0
SetWithExpiry writes a value without an existence precondition using a per-entry expiry. A zero Expiry behaves exactly like Set. An absolute deadline replaces the policy TTL while the configured StaleFor still follows it; NeverExpire ignores both. A deadline at or before the cache clock deletes the key instead of storing an expired value and still supersedes an active load. Non-zero expiries are rejected with ErrInvalidPolicy when the TTL policy is Sliding, because a sliding hit would replace the explicit deadline.
func (*Cache[K, V]) Shutdown ¶
Shutdown cancels active loads, rejects new loads, and waits for loader cleanup within ctx. A nil error means all active loads have completed, including synchronous load observers, not all independent foreground calls. Supplied backends/clients remain caller-owned and are not closed. ErrShutdownIncomplete permits late completion of already-admitted backend work when trusted callbacks or backends ignore cancellation.
type Clock ¶
type Clock interface {
// Now returns the time used for wall-clock deadlines; calls must be bounded.
Now() time.Time
}
Clock supplies time for wall-clock expiration behavior. Implementations must be concurrency-safe, bounded and panic-free. Memory invokes Now under its mutex, so clock callbacks must not re-enter that backend.
type Codec ¶
type Codec[V any] interface { // Encode serializes a borrowed V; callers must not mutate it during encoding. Encode(V) ([]byte, error) // Decode reads borrowed bytes and returns V with codec-defined ownership. Decode([]byte) (V, error) }
Codec serializes and deserializes typed cache values. It is a retained concurrency-safe collaborator, not a generic deep-copy or panic boundary. Decode receives the retrieved record payload; resulting V ownership is defined by the codec. Cache does not clone its returned value.
type Condition ¶
type Condition uint8
Condition controls the atomic precondition applied by Backend.Set.
type Config ¶
type Config[K, V any] struct { // Backend is a retained collaborator; Cache shutdown does not close it. Backend Backend // Keys must be built by NewKeySpace; New does not validate a zero key space. Keys KeySpace[K] // Codec is retained and may be called concurrently; callbacks are not panic-isolated. Codec Codec[V] // TTL sets positive-record freshness, hard staleness and optional sliding reads. TTL TTLPolicy // Clock is retained; its Now method must be safe for concurrent bounded calls. Clock Clock // MaxValue is the positive encoded payload limit, excluding a backend wire header. MaxValue int // MaxBatch bounds sequential bulk items; zero selects 1000. MaxBatch int // Load configures process-local flight, loader, stale and negative policy. Load LoadPolicy // Jitter optionally supplies concurrent TTL sampling; nil selects RandomJitter when needed. Jitter JitterSource // Observer optionally receives synchronous events; Cache owns no exporter lifecycle. Observer Observer }
Config contains all dependencies, limits, and policies for a Cache.
type Entry ¶
type Entry[K, V any] struct { // Key is the logical key, borrowed without generic deep copying. Key K // Value is borrowed for serialization during its sequential Set. Value V }
Entry pairs a logical key with a value for SetMany.
type Error ¶
type Error struct {
// Kind selects a stable category; unknown values add no sentinel.
Kind ErrorKind
// Operation is included in diagnostics; callers must supply a safe action name.
Operation Operation
// contains filtered or unexported fields
}
Error combines a stable semantic kind with a protected cause identity. Construct errors with NewError when a source cause must remain recognizable through errors.Is without exposing its text or concrete type.
func NewError ¶
NewError creates a classified error whose cause remains recognizable with errors.Is but is hidden from formatting and errors.As.
type ErrorKind ¶
type ErrorKind uint8
ErrorKind classifies an operation failure independently of its cause.
const ( // BackendError identifies storage or transport failures. BackendError ErrorKind = iota + 1 // DecodeError identifies malformed encoded values. DecodeError // SchemaMismatchError identifies incompatible payload versions. SchemaMismatchError // InvalidKeyError identifies invalid key configuration or encoding. InvalidKeyError // LimitError identifies a configured resource-limit violation. LimitError // PolicyError identifies an invalid or contradictory policy. PolicyError // LoaderError identifies a source loader failure. LoaderError )
type Event ¶
type Event struct {
// Operation names the action; direct caller strings are not automatically redacted.
Operation Operation
// Outcome names the result; bundled cache producers use the defined constants.
Outcome Outcome
// Duration is non-negative cache-clock elapsed time for bundled producers.
Duration time.Duration
// Size is payload bytes for reads/writes, or retained key+payload bytes for removals.
Size int
}
Event is a redacted semantic observation with no key or value fields.
type Expiry ¶ added in v4.1.0
type Expiry struct {
// contains filtered or unexported fields
}
Expiry selects the freshness deadline of one entry. The zero value defers to the cache's TTLPolicy, RefreshJitter and NegativeTTL, so existing callers keep their fixed-TTL behavior. A non-zero Expiry replaces the fresh TTL and jitter for that entry: ExpireAt is absolute and NeverExpire never becomes stale. Expiry is an immutable value and is safe to share between goroutines.
func ExpireAt ¶ added in v4.1.0
ExpireAt returns an absolute freshness deadline. A positive entry remains fresh before deadline and stays usable as Stale for the configured StaleFor after it; a negative entry ends at deadline. A deadline at or before the cache clock behaves like an already expired write: the key is deleted and nothing is stored. A zero or non-portable deadline, or one whose stale window passes the latest portable instant, is rejected with ErrInvalidTTL.
func NeverExpire ¶ added in v4.1.0
func NeverExpire() Expiry
NeverExpire returns an expiry that keeps an entry fresh until it is explicitly mutated or evicted by its backend. StaleFor does not apply. Remote backends store it with the longest server TTL the portable deadline allows, roughly two centuries from now, rather than a persistent key.
type JSONCodec ¶
type JSONCodec[V any] struct { // Version is the schema byte; Encode rejects zero, Decode only compares it. Version byte // MaxEncodedSize bounds bytes including the version; non-positive selects 1 MiB. MaxEncodedSize int }
JSONCodec stores encoding/json data behind a one-byte schema version. Decode disallows unknown struct fields and trailing documents; map/interface fields and custom JSON methods retain encoding/json semantics. Version zero is rejected by Encode, not independently by Decode. The size cap is a wire bound, not a total heap/CPU bound or limit on user marshaling callbacks.
type JitterSource ¶
type JitterSource interface {
// Duration chooses TTL subtraction; custom results must be within the requested bound.
Duration(time.Duration) time.Duration
}
JitterSource chooses how much time to subtract from a loaded value's TTL.
type KeyEncoder ¶
type KeyEncoder[K any] interface { // EncodeKey returns deterministic borrowed key bytes or an error; size/work are caller-bounded. EncodeKey(K) ([]byte, error) }
KeyEncoder deterministically converts a typed logical key to bytes.
type KeySpace ¶
type KeySpace[K any] struct { // contains filtered or unexported fields }
KeySpace hashes logical keys beneath a namespace, name, and version prefix.
func NewKeySpace ¶
func NewKeySpace[K any]( namespace string, name string, version uint32, encoder KeyEncoder[K], maxKeySize int, ) (KeySpace[K], error)
NewKeySpace validates and constructs an isolated versioned key space.
type LoadPolicy ¶
type LoadPolicy struct {
// MaxConcurrent bounds running loaders; zero selects 64.
MaxConcurrent int
// MaxFlights bounds distinct-key flights, including queued loads and
// completed flights retained by an explicit mutation. Zero defaults to 1024.
MaxFlights int
// MaxWaitersPerKey bounds attached foreground callers per flight; zero selects 1024.
MaxWaitersPerKey int
// NegativeTTL is absence retention; zero disables storage of negative load
// results unless the loader returns a non-zero LoadResult.Expiry.
NegativeTTL time.Duration
// StaleWhileRevalidate serves stale data and admits a shared background refresh.
StaleWhileRevalidate bool
// StaleIfError returns the originally read stale value with a foreground refresh error.
StaleIfError bool
// RefreshJitter is the maximum loaded-value TTL subtraction; it must be below TTL.
RefreshJitter time.Duration
// Timeout bounds each loader call from the moment it acquires a loader
// slot; zero adds no bound and negative values are rejected. A loader
// error after expiry matches ErrLoader and ErrLoadTimeout. Loaders that
// ignore cancellation are not abandoned, and a late success is published.
Timeout time.Duration
// InheritValues exposes the context values, never the cancellation or
// deadline, of the caller that admitted the flight to its loader. Joiners'
// values are not visible. A stale-while-revalidate refresh inherits from
// the stale reader that started it. The admitting context is retained
// until the flight finishes. Use inherited values only for diagnostics
// such as correlation and tracing: the result is shared by every waiter
// and stored for later readers, so anything that changes it, such as a
// tenant or principal, belongs in the key.
InheritValues bool
}
LoadPolicy bounds loading and enables optional negative and stale behavior.
type LoadResult ¶
type LoadResult[V any] struct { // Value is the loader result, shared without deep copying among waiters. Value V // Found distinguishes a present zero/nil value from authoritative absence. Found bool // Expiry optionally replaces the fresh TTL and jitter (found) or NegativeTTL // (absent) for this entry; zero keeps the cache policy. A non-zero Expiry on // an absent result is stored even when NegativeTTL is zero. A passed // deadline deletes the key; waiters still receive this result. Expiry Expiry }
LoadResult is the value and existence result returned by a Loader.
type Loader ¶
type Loader[K, V any] func(context.Context, K) (LoadResult[V], error)
Loader fetches a logical key from its source of truth. It receives a cache-owned context, never a waiter's cancellation or deadline; values are visible only with LoadPolicy.InheritValues. Honor its cancellation, which includes LoadPolicy.Timeout, and bound external calls; returned mutable V is shared among flight waiters. Errors are protected; panic values are discarded as ErrLoaderPanic.
type MutationResult ¶
type MutationResult[K any] struct { // Key is the input key at the corresponding position. Key K // Err is this mutation's failure; other items are still attempted. Err error }
MutationResult reports one bulk mutation error in input order.
type Observer ¶
type Observer interface {
// Observe receives an event synchronously; returned errors and panics are ignored by cache notification.
Observe(context.Context, Event) error
}
Observer receives synchronous semantic events from cache operations. Notification discards returned errors and recovers observer panics, but cannot force a blocked callback to return. Implementations must bound work, support concurrent calls and avoid re-entering publication locks. Contexts can be caller-owned or cache-load-owned; event fields alone are not a redaction engine.
type Operation ¶
type Operation string
Operation names the semantic cache action associated with an event or error.
const ( // OperationGet identifies a read. OperationGet Operation = "get" // OperationSet identifies a write. OperationSet Operation = "set" // OperationDelete identifies invalidation. OperationDelete Operation = "delete" // OperationLoad identifies a source load. OperationLoad Operation = "load" // OperationEvict identifies capacity eviction. OperationEvict Operation = "evict" // OperationExpire identifies deadline expiration. OperationExpire Operation = "expire" )
type Outcome ¶
type Outcome string
Outcome is a low-cardinality semantic operation result.
const ( // OutcomeSuccess identifies a successful mutation or load. OutcomeSuccess Outcome = "success" // OutcomeHit identifies a fresh read. OutcomeHit Outcome = "hit" // OutcomeMiss identifies an absent read. OutcomeMiss Outcome = "miss" // OutcomeStale identifies a stale read. OutcomeStale Outcome = "stale" // OutcomeNegative identifies a negative-cache result. OutcomeNegative Outcome = "negative" // OutcomeRejected identifies a failed conditional mutation. OutcomeRejected Outcome = "rejected" // OutcomeError identifies an operation failure. OutcomeError Outcome = "error" // OutcomeEvicted identifies capacity eviction. OutcomeEvicted Outcome = "evicted" // OutcomeExpired identifies deadline expiration. OutcomeExpired Outcome = "expired" )
type OwnershipBackend ¶
type OwnershipBackend interface {
Backend
// SetIfOwned compares ownership and publishes atomically, or reports loss/failure.
SetIfOwned(context.Context, string, Record, OwnershipGuard) error
}
OwnershipBackend atomically validates ownership and writes one record.
type OwnershipGuard ¶
type OwnershipGuard interface {
// StorageKey returns the external lease storage coordinate; it may be sensitive.
StorageKey() string
// Owner returns the opaque identity to compare with the active owner.
Owner() string
// Token returns the opaque fencing identity to compare, not a numeric order.
Token() string
}
OwnershipGuard identifies backend-authenticated ownership for one protected write. Methods must supply stable values during a call and must not panic. Implementations must return opaque storage coordinates, not logical keys or credentials.
type RandomJitter ¶
type RandomJitter struct{}
RandomJitter samples a non-cryptographic duration in [0, max).
type Record ¶
type Record struct {
// Payload is caller-owned mutable encoded data; Clone isolates its bytes.
Payload []byte
// ExpiresAt is the first instant the value is no longer fresh.
ExpiresAt time.Time
// StaleAt is the hard usability deadline, at or after ExpiresAt.
StaleAt time.Time
// Negative marks authoritative absence and requires an empty payload.
Negative bool
}
Record is the portable value and expiration envelope stored by a Backend.
type Result ¶
type Result[V any] struct { // State is Hit, Miss or Stale on success; inspect the error before zero state. State State // Value is usable for Hit/Stale; generic references are not deep copied. Value V // Negative marks a cached or just-loaded authoritative-absence miss. Negative bool }
Result is the explicit outcome of a typed cache read.
type StringKeyEncoder ¶
type StringKeyEncoder struct{}
StringKeyEncoder encodes strings without conversion.
type TTLPolicy ¶
type TTLPolicy struct {
// TTL is the strictly positive fresh duration.
TTL time.Duration
// StaleFor is additional non-negative hard-retention time after freshness.
StaleFor time.Duration
// Sliding rewrites fresh records on hit with IfPresent, not record-version CAS.
Sliding bool
}
TTLPolicy defines the fresh and stale lifetime of positive records.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
adapters
|
|
|
memory
Package cachememory provides a bounded, concurrency-safe LRU cache adapter.
|
Package cachememory provides a bounded, concurrency-safe LRU cache adapter. |
|
otel
Package cacheotel exports cache events as low-cardinality OpenTelemetry metrics.
|
Package cacheotel exports cache events as low-cardinality OpenTelemetry metrics. |
|
redis
Package cacheredis adapts go-redis/v9 clients to the cache backend contract.
|
Package cacheredis adapts go-redis/v9 clients to the cache backend contract. |
|
service
Package cacheservice adapts explicit cache resources to the service lifecycle without hiding their concrete types.
|
Package cacheservice adapts explicit cache resources to the service lifecycle without hiding their concrete types. |
|
slog
Package cacheslog records redacted cache events with the standard log package.
|
Package cacheslog records redacted cache events with the standard log package. |
|
valkey
Package cachevalkey adapts valkey-go clients to the cache backend contract.
|
Package cachevalkey adapts valkey-go clients to the cache backend contract. |
|
Package cachetest provides a shared backend conformance suite.
|
Package cachetest provides a shared backend conformance suite. |
|
internal
|
|
|
wire
Package wire encodes portable backend records for remote storage.
|
Package wire encodes portable backend records for remote storage. |