cache

package
v1.15.0 Latest Latest
Warning

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

Go to latest
Published: Mar 11, 2026 License: Apache-2.0 Imports: 9 Imported by: 2

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrConflict is raised when our data source returns the same
	// index multiple times.
	ErrConflict = errors.New("a cache index was witnessed more than once")
	// ErrInvalid is raised when there is no cache data e.g. it has
	// not been started.
	ErrInvalid = errors.New("cache invalid")
	// ErrNotFound is returned when the requested index is not in the
	// cache.
	ErrNotFound = errors.New("cache index not found")
	// ErrWorkerPanic is used to handle worker panics.
	ErrWorkerPanic = errors.New("worker panic")
)

Functions

This section is empty.

Types

type Cacheable added in v1.15.0

type Cacheable[T any] interface {
	// Index generates an index for the hash table.
	Index() string
	// Equal is used to detect modifications of the data.
	Equal(other *T) bool
}

Cacheable defines a cacheable type.

type CacheablePointer added in v1.15.0

type CacheablePointer[T any] interface {
	*T
	Cacheable[T]
}

CacheablePointer defines a pointer to a type that implements the Cacheable interface.

type Epoch added in v1.15.0

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

Epoch represents a revision of the cache data.

func (Epoch) Valid added in v1.15.0

func (e Epoch) Valid(previous Epoch) bool

Valid checks if a previous epoch is still valid against the current one.

type GetSnapshot added in v1.15.0

type GetSnapshot[T any] struct {
	// Epoch is the revision of the cache data.  The client can memoize any
	// transformations applied to the items and reuse those until a time
	// when the epoch becomes invalid.
	Epoch Epoch
	// Item is the individual cache item.
	Item *T
}

GetSnapshot is a user view of cache data.

type IndexFunc added in v1.15.0

type IndexFunc[T any, TP CacheablePointer[T]] func(t TP) string

IndexFunc provides the client a way to define how indexes are generated from cache resources. The index must be unique across all resources.

type LRUExpireCache added in v1.0.0

type LRUExpireCache[K comparable, T any] struct {
	// contains filtered or unexported fields
}

LRUExpireCache is a drop in replacement for the apimachinery version that makes it typed with generics, and also data immutable via deep copies.

func NewLRUExpireCache added in v1.0.0

func NewLRUExpireCache[K comparable, T any](maxSize int) *LRUExpireCache[K, T]

func (*LRUExpireCache[K, T]) Add added in v1.0.0

func (c *LRUExpireCache[K, T]) Add(key K, value T, ttl time.Duration)

func (*LRUExpireCache[K, T]) Get added in v1.0.0

func (c *LRUExpireCache[K, T]) Get(key K) (T, bool)

func (*LRUExpireCache[K, T]) ZeroCopy added in v1.14.0

func (c *LRUExpireCache[K, T]) ZeroCopy()

ZeroCopy allows the contents to be modifed, which is probably not what you want, but it is extremely fast, avoiding a deep copy and all the pain reflection inflicts.

type ListSnapshot added in v1.15.0

type ListSnapshot[T any] struct {
	// Epoch is the revision of the cache data.  The client can memoize any
	// transformations applied to the items and reuse those until a time
	// when the epoch becomes invalid.
	Epoch Epoch
	// Items are the individual cache items.  No ordering constraints are placed
	// on the snapshot items as this is likely to be more efficient downstream
	// after any potential filtering oprtations.
	Items []*T
}

ListSnapshot is a user view of cache data.

type RefreshAheadCache added in v1.15.0

type RefreshAheadCache[T any, TP CacheablePointer[T]] struct {
	// contains filtered or unexported fields
}

RefreshAheadCache is a hightly efficient high performance cache implementation for sets of resources.

Synchronization

One of the key observations with a timeout cache that is lazily loaded on a cache miss is that someone needs to pay a performance penalty. This implementation focuses on background synchronization of data either periodically or explicitly through a synchronization operation.

Explicit synchronization is deliberately blocking so that when control is returned back to the client, the expected data is guaranteed to be in the cache ready for subsequent use.

Either the entire cache can be refreshed, which facilitates addition of resources out-of-band, or synchronization of individual resources for example on creation or update to avoid having to perform a potentially costly rebuild.

Read Performance

Bacground synchronization ensures every client read will perform equally well. To facilitate efficient lookups of individual resources in the cache each resource will be indexed via some form of hashing function that uniquely identfies that resource.

The cache features pre-population so it will be ready to use, and this synchronization status can be fed directly into Kubernetes readiness probes to facilitate a seemless rolling upgrade experience.

Read Safety

If we naively passed a slice up to the client, then that could be accidentally mutated through filtering operations such as slices.Delete. The easy fix is to perform a deep copy of the data, but this is costly due to the use of runtime reflection.

We implement a halfway policy that is both performant and also less likely to fall foul of accidental mutation. Cache resources are only ever referred by pointer, facilitating zero copy for individual resources. When a client wishes to list all resources we return a new array that can be mutated pointing to each of the resources, doing only the minimal amount of work as is necessary.

Downstream Performance Optimization

Synchronization events are epochs. When a client lists resources, not only does it return an array of resource pointers, it also returns the epoch for which it is valid for.

This allows clients to memoize any transformations made against the cached resurces and further improve performance. An example of this is JSON encoding which uses runtime type reflection and is relatively costly.

func NewRefreshAheadCache added in v1.15.0

func NewRefreshAheadCache[T any, TP CacheablePointer[T]](refresh RefreshFunc[T, TP], options *RefreshAheadCacheOptions) *RefreshAheadCache[T, TP]

NewRefreshAheadCache constructs a new refresh ahead cache.

func (*RefreshAheadCache[T, TP]) Get added in v1.15.0

func (c *RefreshAheadCache[T, TP]) Get(index string) (*GetSnapshot[T], error)

Get does a zero copy read of a specified item.

func (*RefreshAheadCache[T, TP]) Invalidate added in v1.15.0

func (c *RefreshAheadCache[T, TP]) Invalidate() (err error)

Invalidate performs a synchronous invalidation of the cache and only returns control to the client when the refresh has completed, guaranteeing on success that the cache will contain any new values.

func (*RefreshAheadCache[T, TP]) List added in v1.15.0

func (c *RefreshAheadCache[T, TP]) List() (*ListSnapshot[T], error)

List does a zero copy read of all items.

func (*RefreshAheadCache[T, TP]) Run added in v1.15.0

func (c *RefreshAheadCache[T, TP]) Run(ctx context.Context) error

Run performs a synchronous refresh to pre load cache data and starts the background refresher.

type RefreshAheadCacheOptions added in v1.15.0

type RefreshAheadCacheOptions struct {
	// RefreshPeriod controls how often to refresh data.
	RefreshPeriod time.Duration
}

RefreshAheadCacheOptions allows the cache to be configured in various ways.

type RefreshFunc added in v1.15.0

type RefreshFunc[T any, TP CacheablePointer[T]] func(ctx context.Context) ([]TP, error)

RefreshFunc provides the client a way to define how to load the cache data. It is recommended that any post processing that happens on raw data also occurs during a refresh to hide the cost.

type TimeoutCache

type TimeoutCache[V any] struct {
	// contains filtered or unexported fields
}

TimeoutCache provides a cache with timeout.

func New

func New[V any](refresh time.Duration) *TimeoutCache[V]

New gets a new cache.

func NewWithClock added in v1.11.0

func NewWithClock[V any](refresh time.Duration, c clock) *TimeoutCache[V]

func (*TimeoutCache[V]) Get

func (m *TimeoutCache[V]) Get() (value V, ok bool)

Get returns the cached value if set and it hasn't timed out and returns true. If it has timed out, it will return V's zero value and false, and will need to be set again.

func (*TimeoutCache[V]) Invalidate added in v1.11.0

func (m *TimeoutCache[V]) Invalidate()

func (*TimeoutCache[V]) Set

func (m *TimeoutCache[V]) Set(value V)

Set remembers the value and resets the invalid time based on when the cache was set.

Jump to

Keyboard shortcuts

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