ocache

package
v0.13.8 Latest Latest
Warning

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

Go to latest
Published: Oct 7, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrClosed    = errors.New("object cache closed")
	ErrExists    = errors.New("object exists")
	ErrNotExists = errors.New("object not exists")
	ErrNilValue  = errors.New("nil value")
)
View Source
var ErrLoadPanic = errors.New("loadFunc panicked")

ErrLoadPanic is what every waiter on a load receives when the loadFunc panicked instead of returning; the panic itself propagates to the loading caller.

View Source
var WithCloseTimeout = func(d time.Duration) Option {
	return func(cache *oCache) {
		if d > 0 {
			cache.closeTimeout = d
		}
	}
}

WithCloseTimeout bounds Close's waits on in-flight loads and on entries another closer holds (default 10s). The value.Close calls themselves take no ctx and are not bounded. Non-positive values are ignored.

View Source
var WithGCPeriod = func(gcPeriod time.Duration) Option {
	return func(cache *oCache) {
		cache.gc = gcPeriod
	}
}
View Source
var WithLogger = func(l *zap.SugaredLogger) Option {
	return func(cache *oCache) {
		cache.log = l
	}
}
View Source
var WithTTL = func(ttl time.Duration) Option {
	return func(cache *oCache) {
		cache.ttl = ttl
	}
}

Functions

This section is empty.

Types

type LoadFunc

type LoadFunc func(ctx context.Context, id string) (value Object, err error)

type OCache

type OCache interface {
	// DoLockedIfNotExists does an action if the object with id is not in cache
	// under a global lock, this will prevent a race which otherwise occurs
	// when object is created in parallel with action
	DoLockedIfNotExists(id string, action func() error) error
	// Get gets an object from cache or creates a new one via 'loadFunc';
	// it also refreshes the object's GC deadline.
	// When 'loadFunc' returns a non-nil error, an object will not be stored to cache.
	// A load that completed by the time ctx is done still returns its value.
	// Returns ErrClosed on a closed cache, including for waiters whose load
	// lands after Close.
	Get(ctx context.Context, id string) (value Object, err error)
	// Pick returns value if it's present in cache (will not call loadFunc,
	// does not refresh the GC deadline) — but it waits out an in-flight load
	// for the id, bounded by ctx. Returns ErrClosed on a closed cache.
	Pick(ctx context.Context, id string) (value Object, err error)
	// Add adds new object to cache
	// Returns error when the value is nil, the object exists or the cache is closed
	Add(id string, value Object) (err error)
	// Remove closes and removes object
	Remove(ctx context.Context, id string) (ok bool, err error)
	// RemoveSame closes and removes the object only if the value currently
	// stored under id is exactly the given one (pointer identity). It lets a
	// caller evict a specific instance it owns without racing a newer value
	// that has replaced it under the same id. A value that is not comparable
	// has no identity and is never matched (store such values behind a
	// pointer). Returns ok=true only when this call performed the removal.
	RemoveSame(ctx context.Context, id string, value Object) (ok bool, err error)
	// TryRemove tries to close and to remove the object. ok reports whether
	// this call removed it; (false, nil) means the object declined to close,
	// is still loading, or another closer owns it. A non-nil err can
	// accompany ok=true when the value closed with an error.
	TryRemove(id string) (ok bool, err error)
	// ForEach iterates over all loaded objects, breaks when callback returns false
	ForEach(f func(v Object) (isContinue bool))
	// GC frees not used and expired objects
	// Will automatically called every 'gcPeriod'
	GC()
	// Len returns current cache size
	Len() int
	// Close closes all objects and the cache. The pass is bounded by a close
	// timeout; an entry held past it by an in-flight load or a busy closer is
	// not waited for — its value is closed by that path's own closed-cache
	// branch when it completes.
	Close() (err error)
}

func New

func New(loadFunc LoadFunc, opts ...Option) OCache

type Object

type Object interface {
	Close() (err error)
	TryClose(objectTTL time.Duration) (res bool, err error)
}

type Option

type Option func(*oCache)

func WithPrometheus

func WithPrometheus(reg *prometheus.Registry, namespace, subsystem string) Option

func WithPrometheusMetrics added in v0.8.9

func WithPrometheusMetrics(hit, miss, gc prometheus.Counter, size prometheus.GaugeFunc) Option

type PeekState added in v0.13.7

type PeekState int

PeekState is Peek's verdict about an id.

const (
	// PeekMiss: no entry for id (or the cache is closed)
	PeekMiss PeekState = iota
	// PeekBusy: an entry exists but is still loading or is being closed; a
	// Get or Pick would wait for it
	PeekBusy
	// PeekHit: a loaded value, returned
	PeekHit
)

type Peeker added in v0.13.7

type Peeker interface {
	// Peek returns the value for id only if it is loaded and not being
	// closed, without loading, waiting or allocating: the hot path for
	// callers that handle a miss themselves. With touch a hit refreshes the
	// GC deadline like Get. The state tells a miss from an entry that is
	// loading or closing (a caller that must not act on a false miss waits
	// for the latter, see WaitClosing). Peek counts no metrics: the caller,
	// which decides whether the result is used, accounts for it.
	Peek(id string, touch bool) (value Object, state PeekState)
	// WaitClosing blocks while the entry for id is being closed, bounded by
	// ctx, and returns at once when there is no such entry or it is not
	// closing. It is the wait a caller needs before it can add a replacement
	// for a value whose removal is still running.
	WaitClosing(ctx context.Context, id string) error
}

Peeker is the non-blocking read the cache returned by New offers on top of OCache; kept off that interface so other implementations stay valid.

type PrometheusCollectors added in v0.13.7

type PrometheusCollectors struct {
	Hit, Miss, GC prometheus.Counter
	Size          prometheus.GaugeFunc
}

PrometheusCollectors are the collectors a cache reports through: the ones WithPrometheus builds and registers, exposed for a caller that recreates its cache and so must register them once and hand them to every instance.

func NewPrometheusCollectors added in v0.13.7

func NewPrometheusCollectors(namespace, subsystem string, sizeFn func() int) PrometheusCollectors

NewPrometheusCollectors builds unregistered collectors with the names WithPrometheus would register (<namespace>_<subsystem>_{hit,miss,gc,size}, dots turned into underscores, subsystem defaulting to "cache"). size is read through sizeFn, so it can resolve whichever cache is current.

func (PrometheusCollectors) MustRegister added in v0.13.7

func (c PrometheusCollectors) MustRegister(reg prometheus.Registerer)

MustRegister registers the collectors with reg; like prometheus it panics on a second registration of the same names.

func (PrometheusCollectors) Option added in v0.13.7

func (c PrometheusCollectors) Option() Option

Option makes a cache report through these collectors without registering anything.

Jump to

Keyboard shortcuts

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