cache

package module
v0.12.0 Latest Latest
Warning

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

Go to latest
Published: Oct 8, 2025 License: Apache-2.0 Imports: 11 Imported by: 12

Documentation

Overview

Package cache provides a Store interface for a cache store, along with two implementations of this interface for expiring cache(Cache) and least recently used cache(LRU). Expirable defines an interface for cache with expiring items. This is also implemented by the expiring cache implementation, Cache. The Cache and LRU cache implementations are generic cache. The data type of the value stored in the cache has to be defined when creating the cache. For example, for storing string values in Cache create a string type Cache

cache, err := New[string](10)

The cache implementations are self-instrumenting and export metrics about the internal operations of the cache if it is configured with a metrics registerer.

cache, err := New[string](10, WithMetricsRegisterer(reg))

For recording cache hit/miss metrics associated with a Flux object for which the cache is used, the caller must explicitly record the cache event based on the result of the operation along with the object in the context

got, err := cache.Get("foo")
// Handle any error.
...

if err == ErrNotFound {
  cache.RecordCacheEvent(CacheEventTypeMiss, "GitRepository", "repoA", "testNS")
} else {
  cache.RecordCacheEvent(CacheEventTypeHit, "GitRepository", "repoA", "testNS")
}

When the Flux object associated with the cache metrics is deleted, the metrics can be deleted as follows

cache.DeleteCacheEvent(CacheEventTypeHit, "GitRepository", "repoA", "testNS")
cache.DeleteCacheEvent(CacheEventTypeMiss, "GitRepository", "repoA", "testNS")

Index

Constants

View Source
const (
	// CacheEventTypeMiss is the event type for cache misses.
	CacheEventTypeMiss = "cache_miss"
	// CacheEventTypeHit is the event type for cache hits.
	CacheEventTypeHit = "cache_hit"
	// StatusSuccess is the status for successful cache requests.
	StatusSuccess = "success"
	// StatusFailure is the status for failed cache requests.
	StatusFailure = "failure"
)
View Source
const OperationReconcile = "reconcile"
View Source
const TokenMaxDuration = time.Hour

TokenMaxDuration is the maximum duration that a token can have in the TokenCache. This is used to cap the duration of tokens to avoid storing tokens that are valid for too long.

Variables

View Source
var (
	ErrNotFound    = CacheErrorReason{"NotFound", "object not found"}
	ErrCacheClosed = CacheErrorReason{"CacheClosed", "cache is closed"}
	ErrCacheFull   = CacheErrorReason{"CacheFull", "cache is full"}
	ErrInvalidSize = CacheErrorReason{"InvalidSize", "invalid size"}
)

Functions

func MustMakeMetrics

func MustMakeMetrics(r prometheus.Registerer, m *cacheMetrics)

MustMakeMetrics registers the metrics collectors in the given registerer.

Types

type Cache

type Cache[T any] struct {
	// contains filtered or unexported fields
}

Cache[T] is a thread-safe in-memory key/value store. It can be used to store items with optional expiration.

func New

func New[T any](capacity int, opts ...Options) (*Cache[T], error)

New creates a new cache with the given configuration.

func (Cache) Clear

func (c Cache) Clear()

Clear all index from the cache. This reallocates the underlying array holding the index, so that the memory used by the index is reclaimed. A closed cache cannot be cleared.

func (*Cache[T]) Close

func (c *Cache[T]) Close() error

Close closes the cache. It also stops the expiration eviction process.

func (*Cache[T]) Delete

func (c *Cache[T]) Delete(key string) error

Delete an item from the cache. Does nothing if the key is not in the cache. It actually sets the item expiration to `now“, so that it will be deleted at the cleanup.

func (*Cache[T]) DeleteCacheEvent added in v0.1.0

func (c *Cache[T]) DeleteCacheEvent(event, kind, name, namespace, operation string)

DeleteCacheEvent deletes the cache event (cache_miss or cache_hit) metric for the associated object being reconciled, given their kind, name and namespace.

func (*Cache[T]) Get

func (c *Cache[T]) Get(key string) (T, error)

Get returns an item in the cache for the given key. If no item is found, an error is returned. The caller can record cache hit or miss based on the result with Cache.RecordCacheEvent().

func (*Cache[T]) GetExpiration

func (c *Cache[T]) GetExpiration(key string) (time.Time, error)

GetExpiration returns the expiration for the given key. Returns zero if the key is not in the cache or the item has already expired.

func (*Cache[T]) HasExpired

func (c *Cache[T]) HasExpired(key string) (bool, error)

HasExpired returns true if the item has expired.

func (Cache) ListKeys

func (c Cache) ListKeys() ([]string, error)

ListKeys returns a slice of the keys in the cache.

func (*Cache[T]) RecordCacheEvent added in v0.1.0

func (c *Cache[T]) RecordCacheEvent(event, kind, name, namespace, operation string)

RecordCacheEvent records a cache event (cache_miss or cache_hit) with kind, name and namespace of the associated object being reconciled.

func (Cache) Resize

func (c Cache) Resize(size int) (int, error)

Resize resizes the cache and returns the number of index removed. Size must be greater than zero.

func (*Cache[T]) Set

func (c *Cache[T]) Set(key string, value T) error

Set an item in the cache, existing index will be overwritten. If the cache is full, an error is returned.

func (*Cache[T]) SetExpiration

func (c *Cache[T]) SetExpiration(key string, expiration time.Time) error

SetExpiration sets the expiration for the given key.

type CacheError

type CacheError struct {
	Reason CacheErrorReason
	Err    error
}

func (*CacheError) Error

func (e *CacheError) Error() string

Error returns Err as a string, prefixed with the Reason to provide context.

func (*CacheError) Is

func (e *CacheError) Is(target error) bool

Is returns true if the Reason or Err equals target. It can be used to programmatically place an arbitrary Err in the context of the Cache:

err := &CacheError{Reason: ErrCacheFull, Err: errors.New("arbitrary resize error")}
errors.Is(err, ErrCacheFull)

func (*CacheError) Unwrap

func (e *CacheError) Unwrap() error

Unwrap returns the underlying Err.

type CacheErrorReason

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

CacheErrorReason is a type that represents the reason for a cache error.

func (CacheErrorReason) Error

func (e CacheErrorReason) Error() string

Error gives a human-readable description of the error.

type Expirable

type Expirable[T any] interface {
	Store[T]
	// SetExpiration sets the expiration time for a cached item.
	SetExpiration(key string, expiresAt time.Time) error
	// GetExpiration returns the expiration time of an item.
	GetExpiration(key string) (time.Time, error)
	// HasExpired returns if an item has expired.
	HasExpired(key string) (bool, error)
}

Expirable is an interface for a cache store that supports expiration.

type InvolvedObject added in v0.4.0

type InvolvedObject struct {
	Kind      string
	Name      string
	Namespace string
	Operation string
}

type LRU

type LRU[T any] struct {
	// contains filtered or unexported fields
}

LRU is a thread-safe in-memory key/value store. All methods are safe for concurrent use. All operations are O(1). The hash map lookup is O(1) and so is the doubly linked list insertion/deletion.

The LRU is implemented as a doubly linked list, where the most recently accessed item is at the front of the list and the least recently accessed item is at the back. When an item is accessed, it is moved to the front of the list. When the cache is full, the least recently accessed item is removed from the back of the list.

                                  Cache
           ┌───────────────────────────────────────────────────┐
           │                                                   │
  empty    │     obj         obj          obj          obj     │    empty
┌───────┐  │  ┌───────┐   ┌───────┐     ┌───────┐   ┌───────┐  │  ┌───────┐
│       │  │  │       │   │       │ ... │       │   │       │  │  │       │
│ HEAD  │◄─┼─►│       │◄─►│       │◄───►│       │◄─►│       │◄─┼─►│ TAIL  │
│       │  │  │       │   │       │     │       │   │       │  │  │       │
└───────┘  │  └───────┘   └───────┘     └───────┘   └───────┘  │  └───────┘
           │                                                   │
           │                                                   │
           └───────────────────────────────────────────────────┘

Use the NewLRU function to create a new cache that is ready to use.

func NewLRU

func NewLRU[T any](capacity int, opts ...Options) (*LRU[T], error)

NewLRU creates a new LRU cache with the given capacity.

func (*LRU[T]) Delete

func (c *LRU[T]) Delete(key string) error

Delete removes a node from the list

func (*LRU[T]) DeleteCacheEvent added in v0.1.0

func (c *LRU[T]) DeleteCacheEvent(event, kind, name, namespace, operation string)

DeleteCacheEvent deletes the cache event (cache_miss or cache_hit) metric for the associated object being reconciled, given their kind, name and namespace.

func (*LRU[T]) Get

func (c *LRU[T]) Get(key string) (T, error)

Get returns an item in the cache for the given key. If no item is found, an error is returned. The caller can record cache hit or miss based on the result with LRU.RecordCacheEvent().

func (*LRU[T]) GetIfOrSet added in v0.4.0

func (c *LRU[T]) GetIfOrSet(ctx context.Context,
	key string,
	condition func(T) bool,
	fetch func(context.Context) (T, error),
	opts ...Options,
) (value T, ok bool, err error)

GetIfOrSet returns an item in the cache for the given key if present and if the condition is satisfied, or calls the fetch function to get a new item and stores it in the cache. The operation is thread-safe and atomic. The boolean return value indicates whether the item was retrieved from the cache.

func (*LRU[T]) ListKeys

func (c *LRU[T]) ListKeys() ([]string, error)

ListKeys returns a list of keys in the cache.

func (*LRU[T]) RecordCacheEvent added in v0.1.0

func (c *LRU[T]) RecordCacheEvent(event, kind, name, namespace, operation string)

RecordCacheEvent records a cache event (cache_miss or cache_hit) with kind, name and namespace of the associated object being reconciled.

func (*LRU[T]) Resize

func (c *LRU[T]) Resize(size int) (int, error)

Resize resizes the cache and returns the number of items removed.

func (*LRU[T]) Set

func (c *LRU[T]) Set(key string, value T) error

Set an item in the cache, existing index will be overwritten.

type Options

type Options func(*storeOptions) error

Options is a function that sets the store options.

func WithCleanupInterval

func WithCleanupInterval(interval time.Duration) Options

WithCleanupInterval sets the interval for the cache cleanup.

func WithEventNamespaceLabel added in v0.6.0

func WithEventNamespaceLabel(label string) Options

WithEventNamespaceLabel sets the namespace label for the cache events.

func WithInvolvedObject added in v0.4.0

func WithInvolvedObject(kind, name, namespace, operation string) Options

WithInvolvedObject sets the involved object for the cache metrics.

func WithMaxDuration added in v0.5.0

func WithMaxDuration(duration time.Duration) Options

WithMaxDuration sets the maximum duration for the cache items.

func WithMetricsPrefix added in v0.1.0

func WithMetricsPrefix(prefix string) Options

WithMetricsPrefix sets the metrics prefix for the cache metrics.

func WithMetricsRegisterer

func WithMetricsRegisterer(r prometheus.Registerer) Options

WithMetricsRegisterer sets the Prometheus registerer for the cache metrics.

type Store

type Store[T any] interface {
	// Set adds an item to the store for the given key.
	Set(key string, value T) error
	// Get returns an item stored in the store for the given key.
	Get(key string) (T, error)
	// Delete deletes an item in the store for the given key.
	Delete(key string) error
}

Store is an interface for a cache store.

type Token added in v0.4.0

type Token interface {
	// GetDuration returns the duration for which the token is valid relative to
	// approximately time.Now(). This is used to determine when the token should
	// be refreshed.
	GetDuration() time.Duration
}

Token is an interface that represents an access token that can be used to authenticate with a cloud provider. The only common method is to get the duration of the token, because different providers may have different ways to represent the token. For example, Azure and GCP use an opaque string token, while AWS uses the pair of access key id and secret access key. Consumers of this token should know what type to cast this interface to.

type TokenCache added in v0.4.0

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

TokenCache is a thread-safe cache specialized in storing and retrieving access tokens. It uses an LRU cache as the underlying storage and takes care of expiring tokens in a pessimistic way by storing both a timestamp with a monotonic clock (the Go default) and an absolute timestamp created from the Unix timestamp of when the token was created. The token is considered expired when either timestamps are older than the current time. This strategy ensures that expired tokens aren't kept in the cache for longer than their expiration time. Also, tokens expire on 80% of their lifetime, which is the same strategy used by kubelet for rotating ServiceAccount tokens.

func NewTokenCache added in v0.4.0

func NewTokenCache(capacity int, opts ...Options) (*TokenCache, error)

NewTokenCache returns a new TokenCache with the given capacity.

func (*TokenCache) DeleteEventsForObject added in v0.7.0

func (c *TokenCache) DeleteEventsForObject(kind, name, namespace, operation string)

DeleteEventsForObject deletes all cache events (cache_miss and cache_hit) for the associated object being deleted, given its kind, name and namespace.

func (*TokenCache) GetOrSet added in v0.4.0

func (c *TokenCache) GetOrSet(ctx context.Context,
	key string,
	newToken func(context.Context) (Token, error),
	opts ...Options,
) (Token, bool, error)

GetOrSet returns the token for the given key if present and not expired, or calls the newToken function to get a new token and stores it in the cache. The operation is thread-safe and atomic. The boolean return value indicates whether the token was retrieved from the cache.

type TokenFlags added in v0.7.0

type TokenFlags struct {
	MaxSize     int
	MaxDuration time.Duration
}

TokenFlags contains the CLI flags that can be used to configure the TokenCache.

func (*TokenFlags) BindFlags added in v0.7.0

func (f *TokenFlags) BindFlags(fs *pflag.FlagSet, defaultMaxSize int)

Jump to

Keyboard shortcuts

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