Documentation
¶
Overview ¶
Package lrucache provides in-memory cache with LRU eviction policy, expiration mechanism, and Prometheus metrics.
Example ¶
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/acronis/go-appkit/lrucache"
)
type User struct {
UUID string
Name string
}
type Post struct {
UUID string
Text string
}
func main() {
// Make and register Prometheus metrics collector.
promMetrics := lrucache.NewPrometheusMetricsWithOpts(lrucache.PrometheusMetricsOpts{
Namespace: "my_app", // Will be prepended to all metric names.
ConstLabels: prometheus.Labels{"app_version": "1.2.3"}, // Will be applied to all metrics.
CurriedLabelNames: []string{"entry_type"}, // For distinguishing between cached entities.
})
promMetrics.MustRegister()
// LRU cache for users.
const aliceUUID = "966971df-a592-4e7e-a309-52501016fa44"
const bobUUID = "848adf28-84c1-4259-97a2-acba7cf5c0b6"
usersCache, err := lrucache.New[string, User](100_000,
promMetrics.MustCurryWith(prometheus.Labels{"entry_type": "user"}))
if err != nil {
log.Fatal(err)
}
usersCache.Add(aliceUUID, User{aliceUUID, "Alice"})
usersCache.Add(bobUUID, User{bobUUID, "Bob"})
if user, found := usersCache.Get(aliceUUID); found {
fmt.Printf("User: %s, %s\n", user.UUID, user.Name)
}
if user, found := usersCache.Get(bobUUID); found {
fmt.Printf("User: %s, %s\n", user.UUID, user.Name)
}
// LRU cache for posts.
const post1UUID = "823e50c7-984d-4de3-8a09-92fa21d3cc3b"
const post2UUID = "24707009-ddf6-4e88-bd51-84ae236b7fda"
postsCache, err := lrucache.NewWithOpts[string, Post](1_000,
promMetrics.MustCurryWith(prometheus.Labels{"entry_type": "note"}), lrucache.Options{
DefaultTTL: 5 * time.Minute, // Expired entries are removed during cleanup (see RunPeriodicCleanup method) or when accessed.
})
if err != nil {
log.Fatal(err)
}
cleanupCtx, cleanupCancel := context.WithCancel(context.Background())
defer cleanupCancel()
go postsCache.RunPeriodicCleanup(cleanupCtx, 10*time.Minute) // Run cleanup every 10 minutes.
postsCache.Add(post1UUID, Post{post1UUID, "Lorem ipsum dolor sit amet..."})
if post, found := postsCache.Get(post1UUID); found {
fmt.Printf("Post: %s, %s\n", post.UUID, post.Text)
}
if _, found := postsCache.Get(post2UUID); !found {
fmt.Printf("Post: %s is missing\n", post2UUID)
}
// The following Prometheus metrics will be exposed:
// my_app_cache_entries_amount{app_version="1.2.3",entry_type="note"} 1
// my_app_cache_entries_amount{app_version="1.2.3",entry_type="user"} 2
// my_app_cache_hits_total{app_version="1.2.3",entry_type="note"} 1
// my_app_cache_hits_total{app_version="1.2.3",entry_type="user"} 2
// my_app_cache_misses_total{app_version="1.2.3",entry_type="note"} 1
fmt.Printf("Users: %d\n", usersCache.Len())
fmt.Printf("Posts: %d\n", postsCache.Len())
}
Output: User: 966971df-a592-4e7e-a309-52501016fa44, Alice User: 848adf28-84c1-4259-97a2-acba7cf5c0b6, Bob Post: 823e50c7-984d-4de3-8a09-92fa21d3cc3b, Lorem ipsum dolor sit amet... Post: 24707009-ddf6-4e88-bd51-84ae236b7fda is missing Users: 2 Posts: 1
Index ¶
- type LRUCache
- func (c *LRUCache[K, V]) Add(key K, value V)
- func (c *LRUCache[K, V]) AddWithTTL(key K, value V, ttl time.Duration)
- func (c *LRUCache[K, V]) Get(key K) (value V, ok bool)
- func (c *LRUCache[K, V]) GetOrAdd(key K, valueProvider func() V) (value V, exists bool)
- func (c *LRUCache[K, V]) GetOrAddWithTTL(key K, valueProvider func() V, ttl time.Duration) (value V, exists bool)
- func (c *LRUCache[K, V]) Len() int
- func (c *LRUCache[K, V]) Purge()
- func (c *LRUCache[K, V]) Remove(key K) bool
- func (c *LRUCache[K, V]) Resize(size int) (evicted int)
- func (c *LRUCache[K, V]) RunPeriodicCleanup(ctx context.Context, cleanupInterval time.Duration)
- type MetricsCollector
- type Options
- type PrometheusMetrics
- func (pm *PrometheusMetrics) AddEvictions(n int)
- func (pm *PrometheusMetrics) IncHits()
- func (pm *PrometheusMetrics) IncMisses()
- func (pm *PrometheusMetrics) MustCurryWith(labels prometheus.Labels) *PrometheusMetrics
- func (pm *PrometheusMetrics) MustRegister()
- func (pm *PrometheusMetrics) SetAmount(amount int)
- func (pm *PrometheusMetrics) Unregister()
- type PrometheusMetricsOpts
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type LRUCache ¶
type LRUCache[K comparable, V any] struct { // contains filtered or unexported fields }
LRUCache represents an LRU cache with eviction mechanism and Prometheus metrics.
func New ¶
func New[K comparable, V any](maxEntries int, metricsCollector MetricsCollector) (*LRUCache[K, V], error)
New creates a new LRUCache with the provided maximum number of entries and metrics collector.
func NewWithOpts ¶ added in v1.10.0
func NewWithOpts[K comparable, V any](maxEntries int, metricsCollector MetricsCollector, opts Options) (*LRUCache[K, V], error)
NewWithOpts creates a new LRUCache with the provided maximum number of entries, metrics collector, and options. Metrics collector is used to collect statistics about cache usage. It can be nil, in this case, metrics will be disabled.
func (*LRUCache[K, V]) Add ¶
func (c *LRUCache[K, V]) Add(key K, value V)
Add adds a value to the cache with the provided key and type. If the cache is full, the oldest entry will be removed.
func (*LRUCache[K, V]) AddWithTTL ¶ added in v1.10.0
AddWithTTL adds a value to the cache with the provided key, type, and TTL. If the cache is full, the oldest entry will be removed. Please note that expired entries are not removed immediately, but only when they are accessed or during periodic cleanup (see RunPeriodicCleanup).
func (*LRUCache[K, V]) GetOrAdd ¶ added in v1.3.0
GetOrAdd returns a value from the cache by the provided key. If the key does not exist, it adds a new value to the cache.
func (*LRUCache[K, V]) GetOrAddWithTTL ¶ added in v1.10.0
func (c *LRUCache[K, V]) GetOrAddWithTTL(key K, valueProvider func() V, ttl time.Duration) (value V, exists bool)
GetOrAddWithTTL returns a value from the cache by the provided key. If the key does not exist, it adds a new value to the cache with the provided TTL. Please note that expired entries are not removed immediately, but only when they are accessed or during periodic cleanup (see RunPeriodicCleanup).
func (*LRUCache[K, V]) Purge ¶
func (c *LRUCache[K, V]) Purge()
Purge clears the cache. Keep in mind that this method does not reset the cache size and does not reset Prometheus metrics except for the total number of entries. All removed entries will not be counted as evictions.
func (*LRUCache[K, V]) Resize ¶
Resize changes the cache size and returns the number of evicted entries.
func (*LRUCache[K, V]) RunPeriodicCleanup ¶ added in v1.10.0
RunPeriodicCleanup runs a cycle of periodic cleanup of expired entries. Entries without expiration time are not affected. It's supposed to be run in a separate goroutine.
type MetricsCollector ¶
type MetricsCollector interface {
// SetAmount sets the total number of entries in the cache.
SetAmount(int)
// IncHits increments the total number of successfully found keys in the cache.
IncHits()
// IncMisses increments the total number of not found keys in the cache.
IncMisses()
// AddEvictions increments the total number of evicted entries.
AddEvictions(int)
}
MetricsCollector represents a collector of metrics to analyze how (effectively or not) cache is used.
type Options ¶ added in v1.10.0
type Options struct {
// DefaultTTL is the default TTL for the cache entries.
// Please note that expired entries are not removed immediately,
// but only when they are accessed or during periodic cleanup (see RunPeriodicCleanup).
DefaultTTL time.Duration
}
Options represents options for the cache.
type PrometheusMetrics ¶ added in v1.3.0
type PrometheusMetrics struct {
EntriesAmount *prometheus.GaugeVec
HitsTotal *prometheus.CounterVec
MissesTotal *prometheus.CounterVec
EvictionsTotal *prometheus.CounterVec
}
PrometheusMetrics represents a Prometheus metrics for the cache.
func NewPrometheusMetrics ¶ added in v1.3.0
func NewPrometheusMetrics() *PrometheusMetrics
NewPrometheusMetrics creates a new instance of PrometheusMetrics with default options.
func NewPrometheusMetricsWithOpts ¶ added in v1.3.0
func NewPrometheusMetricsWithOpts(opts PrometheusMetricsOpts) *PrometheusMetrics
NewPrometheusMetricsWithOpts creates a new instance of PrometheusMetrics with the provided options.
func (*PrometheusMetrics) AddEvictions ¶ added in v1.3.0
func (pm *PrometheusMetrics) AddEvictions(n int)
AddEvictions increments the total number of evicted entries.
func (*PrometheusMetrics) IncHits ¶ added in v1.3.0
func (pm *PrometheusMetrics) IncHits()
IncHits increments the total number of successfully found keys in the cache.
func (*PrometheusMetrics) IncMisses ¶ added in v1.3.0
func (pm *PrometheusMetrics) IncMisses()
IncMisses increments the total number of not found keys in the cache.
func (*PrometheusMetrics) MustCurryWith ¶ added in v1.3.0
func (pm *PrometheusMetrics) MustCurryWith(labels prometheus.Labels) *PrometheusMetrics
MustCurryWith curries the metrics collector with the provided labels.
func (*PrometheusMetrics) MustRegister ¶ added in v1.3.0
func (pm *PrometheusMetrics) MustRegister()
MustRegister does registration of metrics collector in Prometheus and panics if any error occurs.
func (*PrometheusMetrics) SetAmount ¶ added in v1.3.0
func (pm *PrometheusMetrics) SetAmount(amount int)
SetAmount sets the total number of entries in the cache.
func (*PrometheusMetrics) Unregister ¶ added in v1.3.0
func (pm *PrometheusMetrics) Unregister()
Unregister cancels registration of metrics collector in Prometheus.
type PrometheusMetricsOpts ¶ added in v1.3.0
type PrometheusMetricsOpts struct {
// Namespace is a namespace for metrics. It will be prepended to all metric names.
Namespace string
// ConstLabels is a set of labels that will be applied to all metrics.
ConstLabels prometheus.Labels
// CurriedLabelNames is a list of label names that will be curried with the provided labels.
// See PrometheusMetrics.MustCurryWith method for more details.
// Keep in mind that if this list is not empty,
// PrometheusMetrics.MustCurryWith method must be called further with the same labels.
// Otherwise, the collector will panic.
CurriedLabelNames []string
}
PrometheusMetricsOpts represents options for PrometheusMetrics.