Documentation ¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type LoadFunc ¶
LoadFunc computes a value. It should respect cancellation (return with cancellation error).
type LoadOpts ¶
type LoadOpts struct {
// contains filtered or unexported fields
}
LoadOpts configures how long a LoadFunc result should be cached. Cache settings overwrite each other; last write wins. Default is don't cache at all. Callers should synchronize their calls themselves if using multiple goroutines (this is not expected).
func (*LoadOpts) CacheForever ¶
func (o *LoadOpts) CacheForever()
type Map ¶
type Map struct {
// contains filtered or unexported fields
}
Map is a keyed collection of Values. Map{} is ready to use. (*Map)(nil) is valid and never caches or shares results for any key. Maps are concurrency-safe. They must not be copied.
Implementation notes:
Compared to sync.Map, this Map is not sophisticated in terms of optimizing for high concurrency with disjoint sets of keys. It could probably be improved.
Loading on-demand, without repeated value computation, is reminiscent of Guava's LoadingCache: https://github.com/google/guava/wiki/CachesExplained
func (*Map) GetOrCreate ¶
GetOrCreate returns an existing or new Value associated with key. Note: If m == nil, returns nil, a never-caching Value.
type Value ¶
type Value struct {
// contains filtered or unexported fields
}
Value manages the loading (calculation) and storing of a cache value. It's designed for use cases where loading is slow. Concurrency is well-supported:
- Only one load is in progress at a time, even if concurrent callers request the value.
- Cancellation is respected for loading: a caller's load function is invoked with their context. If it respects cancellation and returns an error immediately, the caller's GetOrLoad does, too.
- Cancellation is respected for waiting: if a caller's context is canceled while they're waiting for another in-progress load (not their own), the caller's GetOrLoad returns immediately with the cancellation error.
Simpler mechanisms (like just locking a sync.Mutex when starting computation) don't achieve all of these (in the mutex example, cancellation is not respected while waiting on Lock()).
The original use case was reading rarely-changing data via RPC while letting users cancel the operation (Ctrl-C in their terminal). Very different uses (very fast computations or extremely high concurrency) may not work as well; they're at least not tested. Memory overhead may be quite large if small values are cached.
Value{} is ready to use. (*Value)(nil) is valid and just never caches or shares a result (every get loads). Value must not be copied.
Time-based expiration is optional. See LoadFunc and LoadOpts.
func (*Value) GetOrLoad ¶
GetOrLoad either copies a cached value to dataPtr or runs load and then copies dataPtr's value into the cache. A properly-written load writes dataPtr's value. Example:
var result string err := value.GetOrLoad(ctx, &result, func(ctx context.Context, opts *loadingcache.LoadOpts) error { var err error result, err = doExpensiveThing(ctx) opts.CacheFor(time.Hour) return err })
dataPtr must be a pointer to a copyable value (slice, int, struct without Mutex, etc.).
Value does not cache errors. Consider caching a value containing an error, like struct{result int; err error} if desired.