Documentation
¶
Overview ¶
Package cache provides a comprehensive caching solution with multiple backends and advanced features like TTL, LRU eviction, serialization, and distributed caching.
It supports in-memory caching with LRU eviction, Redis-backed distributed caching, and provides features like:
- TTL (Time To Live) support
- LRU (Least Recently Used) eviction
- Automatic serialization/deserialization
- Cache statistics and monitoring
- Namespace support for multi-tenant applications
- Bulk operations (GetMulti, SetMulti, DeleteMulti)
- Cache warming and preloading
- Event callbacks (OnSet, OnGet, OnDelete, OnEvict)
- Compression support for large values
- Circuit breaker pattern for external cache failures
Example usage:
package main
import (
"context"
"time"
"github.com/valentin-kaiser/go-core/cache"
)
func main() {
// Create an in-memory cache with LRU eviction
memCache := cache.NewMemoryCache().
WithMaxSize(1000).
WithDefaultTTL(time.Hour).
WithLRUEviction(true)
// Create a Redis-backed cache
redisCache := cache.NewRedisCache(cache.RedisConfig{
Addr: "localhost:6379",
Password: "",
DB: 0,
})
// Create a multi-tier cache (L1: memory, L2: Redis)
tieredCache := cache.NewTieredCache(memCache, redisCache)
// Use the cache
ctx := context.Background()
// Set a value with TTL
err := tieredCache.Set(ctx, "user:123", user, time.Minute*30)
if err != nil {
panic(err)
}
// Get a value
var cachedUser User
found, err := tieredCache.Get(ctx, "user:123", &cachedUser)
if err != nil {
panic(err)
}
if found {
fmt.Printf("Found user: %+v\n", cachedUser)
}
}
Index ¶
- type BaseCache
- type Cache
- type Config
- type Error
- type Event
- type EventHandler
- type EventType
- type Item
- type JSONSerializer
- type MemoryCache
- func (mc *MemoryCache) Clear(_ context.Context) error
- func (mc *MemoryCache) Close() error
- func (mc *MemoryCache) Delete(_ context.Context, key string) error
- func (mc *MemoryCache) DeleteMulti(ctx context.Context, keys []string) error
- func (mc *MemoryCache) Exists(_ context.Context, key string) (bool, error)
- func (mc *MemoryCache) Get(_ context.Context, key string, dest interface{}) (bool, error)
- func (mc *MemoryCache) GetKeys() []string
- func (mc *MemoryCache) GetMemoryUsage() int64
- func (mc *MemoryCache) GetMulti(ctx context.Context, keys []string) (map[string]interface{}, error)
- func (mc *MemoryCache) GetSize() int64
- func (mc *MemoryCache) GetTTL(_ context.Context, key string) (time.Duration, error)
- func (mc *MemoryCache) Set(_ context.Context, key string, value interface{}, ttl time.Duration) error
- func (mc *MemoryCache) SetMulti(ctx context.Context, items map[string]interface{}, ttl time.Duration) error
- func (mc *MemoryCache) SetTTL(_ context.Context, key string, ttl time.Duration) error
- func (mc *MemoryCache) WithCleanupInterval(interval time.Duration) *MemoryCache
- func (mc *MemoryCache) WithDefaultTTL(ttl time.Duration) *MemoryCache
- func (mc *MemoryCache) WithEventHandler(handler EventHandler) *MemoryCache
- func (mc *MemoryCache) WithLRUEviction(enabled bool) *MemoryCache
- func (mc *MemoryCache) WithMaxSize(maxSize int64) *MemoryCache
- type NoOpSerializer
- type RedisCache
- func (rc *RedisCache) Clear(ctx context.Context) error
- func (rc *RedisCache) Close() error
- func (rc *RedisCache) Decrement(ctx context.Context, key string, delta int64) (int64, error)
- func (rc *RedisCache) Delete(ctx context.Context, key string) error
- func (rc *RedisCache) DeleteMulti(ctx context.Context, keys []string) error
- func (rc *RedisCache) Exists(ctx context.Context, key string) (bool, error)
- func (rc *RedisCache) FlushDB(ctx context.Context) error
- func (rc *RedisCache) Get(ctx context.Context, key string, dest interface{}) (bool, error)
- func (rc *RedisCache) GetClient() *redis.Client
- func (rc *RedisCache) GetInfo(ctx context.Context) (map[string]string, error)
- func (rc *RedisCache) GetMulti(ctx context.Context, keys []string) (map[string]interface{}, error)
- func (rc *RedisCache) GetSet(ctx context.Context, key string, value interface{}) (interface{}, bool, error)
- func (rc *RedisCache) GetTTL(ctx context.Context, key string) (time.Duration, error)
- func (rc *RedisCache) Increment(ctx context.Context, key string, delta int64) (int64, error)
- func (rc *RedisCache) Ping(ctx context.Context) error
- func (rc *RedisCache) Set(ctx context.Context, key string, value interface{}, ttl time.Duration) error
- func (rc *RedisCache) SetMulti(ctx context.Context, items map[string]interface{}, ttl time.Duration) error
- func (rc *RedisCache) SetNX(ctx context.Context, key string, value interface{}, ttl time.Duration) (bool, error)
- func (rc *RedisCache) SetTTL(ctx context.Context, key string, ttl time.Duration) error
- func (rc *RedisCache) WithDefaultTTL(ttl time.Duration) *RedisCache
- func (rc *RedisCache) WithEventHandler(handler EventHandler) *RedisCache
- func (rc *RedisCache) WithNamespace(namespace string) *RedisCache
- type RedisConfig
- type Serializer
- type Stats
- type TieredCache
- func (tc *TieredCache) Clear(ctx context.Context) error
- func (tc *TieredCache) Close() error
- func (tc *TieredCache) Delete(ctx context.Context, key string) error
- func (tc *TieredCache) DeleteMulti(ctx context.Context, keys []string) error
- func (tc *TieredCache) Exists(ctx context.Context, key string) (bool, error)
- func (tc *TieredCache) Get(ctx context.Context, key string, dest interface{}) (bool, error)
- func (tc *TieredCache) GetL1Cache() Cache
- func (tc *TieredCache) GetL2Cache() Cache
- func (tc *TieredCache) GetMulti(ctx context.Context, keys []string) (map[string]interface{}, error)
- func (tc *TieredCache) GetStats() Stats
- func (tc *TieredCache) GetTTL(ctx context.Context, key string) (time.Duration, error)
- func (tc *TieredCache) GetTieredStats() map[string]Stats
- func (tc *TieredCache) InvalidateL1(ctx context.Context, key string) error
- func (tc *TieredCache) Set(ctx context.Context, key string, value interface{}, ttl time.Duration) error
- func (tc *TieredCache) SetMulti(ctx context.Context, items map[string]interface{}, ttl time.Duration) error
- func (tc *TieredCache) SetTTL(ctx context.Context, key string, ttl time.Duration) error
- func (tc *TieredCache) WarmupL1(ctx context.Context, keys []string) error
- func (tc *TieredCache) WithEventHandler(handler EventHandler) *TieredCache
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type BaseCache ¶
type BaseCache struct {
// contains filtered or unexported fields
}
BaseCache provides common functionality for cache implementations
func NewBaseCache ¶
NewBaseCache creates a new base cache with the given configuration
type Cache ¶
type Cache interface {
// Get retrieves a value from the cache and deserializes it into the provided destination
Get(ctx context.Context, key string, dest interface{}) (bool, error)
// Set stores a value in the cache with the specified TTL
Set(ctx context.Context, key string, value interface{}, ttl time.Duration) error
// Delete removes a value from the cache
Delete(ctx context.Context, key string) error
// Exists checks if a key exists in the cache
Exists(ctx context.Context, key string) (bool, error)
// Clear removes all entries from the cache
Clear(ctx context.Context) error
// GetMulti retrieves multiple values from the cache
GetMulti(ctx context.Context, keys []string) (map[string]interface{}, error)
// SetMulti stores multiple values in the cache
SetMulti(ctx context.Context, items map[string]interface{}, ttl time.Duration) error
// DeleteMulti removes multiple values from the cache
DeleteMulti(ctx context.Context, keys []string) error
// GetTTL returns the remaining TTL for a key
GetTTL(ctx context.Context, key string) (time.Duration, error)
// SetTTL updates the TTL for an existing key
SetTTL(ctx context.Context, key string, ttl time.Duration) error
// GetStats returns cache statistics
GetStats() Stats
// Close closes the cache and releases resources
Close() error
}
Cache defines the interface for cache implementations
type Config ¶
type Config struct {
MaxSize int64 `json:"max_size"`
DefaultTTL time.Duration `json:"default_ttl"`
CleanupInterval time.Duration `json:"cleanup_interval"`
EnableLRU bool `json:"enable_lru"`
EnableStats bool `json:"enable_stats"`
EnableEvents bool `json:"enable_events"`
Namespace string `json:"namespace"`
Serializer Serializer `json:"-"`
EventHandler EventHandler `json:"-"`
}
Config holds common configuration for cache implementations
func DefaultConfig ¶
func DefaultConfig() Config
DefaultConfig returns a default cache configuration
type Error ¶
Error represents a cache-specific error
func NewCacheError ¶
NewCacheError creates a new cache error
type Event ¶
type Event struct {
Type EventType `json:"type"`
Key string `json:"key"`
Value interface{} `json:"value,omitempty"`
Timestamp time.Time `json:"timestamp"`
Namespace string `json:"namespace,omitempty"`
Error error `json:"error,omitempty"`
}
Event represents a cache event
type EventHandler ¶
type EventHandler func(event Event)
EventHandler is a function that handles cache events
type EventType ¶
type EventType int
EventType represents cache event types
const ( // EventSet represents a cache set event EventSet EventType = iota // EventGet represents a cache get event EventGet // EventDelete represents a cache delete event EventDelete // EventEvict represents a cache eviction event EventEvict // EventExpire represents a cache expiration event EventExpire // EventClear represents a cache clear event EventClear )
type Item ¶
type Item struct {
Key string `json:"key"`
Value interface{} `json:"value"`
ExpiresAt time.Time `json:"expires_at"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
AccessAt time.Time `json:"access_at"`
TTL time.Duration `json:"ttl"`
Size int64 `json:"size"`
Namespace string `json:"namespace,omitempty"`
}
Item represents a cache item with metadata
type JSONSerializer ¶
type JSONSerializer struct{}
JSONSerializer implements JSON serialization
func (*JSONSerializer) Deserialize ¶
func (s *JSONSerializer) Deserialize(data []byte, dest interface{}) error
Deserialize deserializes JSON data into the destination
func (*JSONSerializer) Serialize ¶
func (s *JSONSerializer) Serialize(value interface{}) ([]byte, error)
Serialize serializes a value to JSON
type MemoryCache ¶
type MemoryCache struct {
*BaseCache
// contains filtered or unexported fields
}
MemoryCache implements an in-memory cache with LRU eviction support
func NewMemoryCache ¶
func NewMemoryCache() *MemoryCache
NewMemoryCache creates a new in-memory cache with default configuration. The default settings include LRU eviction, 1000 item max size, 1 hour default TTL, and 5-minute cleanup intervals. For custom settings, use NewMemoryCacheWithConfig.
Example usage:
cache := cache.NewMemoryCache() err := cache.Set(ctx, "key", "value", time.Hour)
func NewMemoryCacheWithConfig ¶
func NewMemoryCacheWithConfig(config Config) *MemoryCache
NewMemoryCacheWithConfig creates a new in-memory cache with custom configuration. This allows fine-tuning of cache behavior including size limits, TTL settings, LRU eviction policies, cleanup intervals, and serialization options.
Example usage:
config := cache.Config{
MaxSize: 5000,
DefaultTTL: time.Minute * 30,
CleanupInterval: time.Minute,
EnableLRU: true,
}
cache := cache.NewMemoryCacheWithConfig(config)
func (*MemoryCache) Clear ¶
func (mc *MemoryCache) Clear(_ context.Context) error
Clear removes all entries from the cache
func (*MemoryCache) Close ¶
func (mc *MemoryCache) Close() error
Close closes the cache and stops the cleanup goroutine
func (*MemoryCache) Delete ¶
func (mc *MemoryCache) Delete(_ context.Context, key string) error
Delete removes a value from the cache
func (*MemoryCache) DeleteMulti ¶
func (mc *MemoryCache) DeleteMulti(ctx context.Context, keys []string) error
DeleteMulti removes multiple values from the cache
func (*MemoryCache) GetKeys ¶
func (mc *MemoryCache) GetKeys() []string
GetKeys returns all keys in the cache (useful for debugging)
func (*MemoryCache) GetMemoryUsage ¶
func (mc *MemoryCache) GetMemoryUsage() int64
GetMemoryUsage returns the current memory usage in bytes
func (*MemoryCache) GetSize ¶
func (mc *MemoryCache) GetSize() int64
GetSize returns the current number of items in the cache
func (*MemoryCache) Set ¶
func (mc *MemoryCache) Set(_ context.Context, key string, value interface{}, ttl time.Duration) error
Set stores a value in the cache
func (*MemoryCache) SetMulti ¶
func (mc *MemoryCache) SetMulti(ctx context.Context, items map[string]interface{}, ttl time.Duration) error
SetMulti stores multiple values in the cache
func (*MemoryCache) WithCleanupInterval ¶
func (mc *MemoryCache) WithCleanupInterval(interval time.Duration) *MemoryCache
WithCleanupInterval sets the interval for cleaning up expired items
func (*MemoryCache) WithDefaultTTL ¶
func (mc *MemoryCache) WithDefaultTTL(ttl time.Duration) *MemoryCache
WithDefaultTTL sets the default TTL for cache items
func (*MemoryCache) WithEventHandler ¶
func (mc *MemoryCache) WithEventHandler(handler EventHandler) *MemoryCache
WithEventHandler sets the event handler for cache events
func (*MemoryCache) WithLRUEviction ¶
func (mc *MemoryCache) WithLRUEviction(enabled bool) *MemoryCache
WithLRUEviction enables or disables LRU eviction
func (*MemoryCache) WithMaxSize ¶
func (mc *MemoryCache) WithMaxSize(maxSize int64) *MemoryCache
WithMaxSize sets the maximum number of items in the cache
type NoOpSerializer ¶
type NoOpSerializer struct{}
NoOpSerializer implements no serialization (for already serialized data)
func (*NoOpSerializer) Deserialize ¶
func (s *NoOpSerializer) Deserialize(data []byte, dest interface{}) error
Deserialize copies the data to the destination if it's *[]byte or *string
func (*NoOpSerializer) Serialize ¶
func (s *NoOpSerializer) Serialize(value interface{}) ([]byte, error)
Serialize returns the value as-is if it's []byte, otherwise returns an error
type RedisCache ¶
type RedisCache struct {
*BaseCache
// contains filtered or unexported fields
}
RedisCache implements a Redis-backed cache
func NewRedisCache ¶
func NewRedisCache(config RedisConfig) *RedisCache
NewRedisCache creates a new Redis-backed cache with default cache configuration. It establishes a new Redis client connection using the provided Redis configuration and applies default cache settings (LRU eviction, 1 hour TTL, etc.).
Example usage:
config := cache.RedisConfig{
Addr: "localhost:6379",
Password: "",
DB: 0,
}
cache := cache.NewRedisCache(config)
func NewRedisCacheWithCacheConfig ¶
func NewRedisCacheWithCacheConfig(redisConfig RedisConfig, cacheConfig Config) *RedisCache
NewRedisCacheWithCacheConfig creates a new Redis-backed cache with both custom Redis connection settings and cache configuration. This provides the most flexibility for configuring both the Redis client and cache behavior.
func NewRedisCacheWithClient ¶
func NewRedisCacheWithClient(client *redis.Client) *RedisCache
NewRedisCacheWithClient creates a new Redis-backed cache using an existing Redis client. This is useful when you want to share a Redis client across multiple cache instances or when you need custom Redis client configuration that's not supported by RedisConfig.
func NewRedisCacheWithConfig ¶
func NewRedisCacheWithConfig(client *redis.Client, config Config) *RedisCache
NewRedisCacheWithConfig creates a new Redis-backed cache with an existing Redis client and custom cache configuration. This allows fine-tuning of cache behavior while reusing an existing Redis connection.
func (*RedisCache) Clear ¶
func (rc *RedisCache) Clear(ctx context.Context) error
Clear removes all entries from the cache (only works with namespace)
func (*RedisCache) Delete ¶
func (rc *RedisCache) Delete(ctx context.Context, key string) error
Delete removes a value from the cache
func (*RedisCache) DeleteMulti ¶
func (rc *RedisCache) DeleteMulti(ctx context.Context, keys []string) error
DeleteMulti removes multiple values from the cache
func (*RedisCache) FlushDB ¶
func (rc *RedisCache) FlushDB(ctx context.Context) error
FlushDB flushes the current Redis database
func (*RedisCache) GetClient ¶
func (rc *RedisCache) GetClient() *redis.Client
GetClient returns the underlying Redis client for advanced operations
func (*RedisCache) GetSet ¶
func (rc *RedisCache) GetSet(ctx context.Context, key string, value interface{}) (interface{}, bool, error)
GetSet atomically sets a new value and returns the old value
func (*RedisCache) Ping ¶
func (rc *RedisCache) Ping(ctx context.Context) error
Ping tests the Redis connection
func (*RedisCache) Set ¶
func (rc *RedisCache) Set(ctx context.Context, key string, value interface{}, ttl time.Duration) error
Set stores a value in the cache
func (*RedisCache) SetMulti ¶
func (rc *RedisCache) SetMulti(ctx context.Context, items map[string]interface{}, ttl time.Duration) error
SetMulti stores multiple values in the cache
func (*RedisCache) SetNX ¶
func (rc *RedisCache) SetNX(ctx context.Context, key string, value interface{}, ttl time.Duration) (bool, error)
SetNX sets a key only if it doesn't exist (atomic operation)
func (*RedisCache) WithDefaultTTL ¶
func (rc *RedisCache) WithDefaultTTL(ttl time.Duration) *RedisCache
WithDefaultTTL sets the default TTL for cache items
func (*RedisCache) WithEventHandler ¶
func (rc *RedisCache) WithEventHandler(handler EventHandler) *RedisCache
WithEventHandler sets the event handler for cache events
func (*RedisCache) WithNamespace ¶
func (rc *RedisCache) WithNamespace(namespace string) *RedisCache
WithNamespace sets the namespace for cache keys
type RedisConfig ¶
type RedisConfig struct {
Addr string `json:"addr"`
Password string `json:"password"`
DB int `json:"db"`
PoolSize int `json:"pool_size"`
MinIdleConns int `json:"min_idle_conns"`
MaxRetries int `json:"max_retries"`
DialTimeout time.Duration `json:"dial_timeout"`
ReadTimeout time.Duration `json:"read_timeout"`
WriteTimeout time.Duration `json:"write_timeout"`
IdleTimeout time.Duration `json:"idle_timeout"`
}
RedisConfig holds configuration for Redis cache
func DefaultRedisConfig ¶
func DefaultRedisConfig() RedisConfig
DefaultRedisConfig returns a default Redis configuration
func (*RedisConfig) Changed ¶
func (rc *RedisConfig) Changed(n *RedisConfig) bool
Changed checks if the Redis configuration has changed compared to another configuration.
type Serializer ¶
type Serializer interface {
Serialize(value interface{}) ([]byte, error)
Deserialize(data []byte, dest interface{}) error
}
Serializer defines the interface for value serialization
type Stats ¶
type Stats struct {
Hits int64 `json:"hits"`
Misses int64 `json:"misses"`
Sets int64 `json:"sets"`
Deletes int64 `json:"deletes"`
Evictions int64 `json:"evictions"`
Size int64 `json:"size"`
MaxSize int64 `json:"max_size"`
HitRatio float64 `json:"hit_ratio"`
Memory int64 `json:"memory_bytes"`
Errors int64 `json:"errors"`
LastError string `json:"last_error,omitempty"`
LastErrorAt time.Time `json:"last_error_at,omitempty"`
}
Stats represents cache statistics
type TieredCache ¶
type TieredCache struct {
*BaseCache
// contains filtered or unexported fields
}
TieredCache implements a multi-tier cache system (e.g., L1: Memory, L2: Redis)
func NewTieredCache ¶
func NewTieredCache(l1Cache, l2Cache Cache) *TieredCache
NewTieredCache creates a new multi-tier cache with L1 and L2 cache implementations. The L1 cache is typically a fast, small cache (like memory) while L2 is a larger, persistent cache (like Redis). Reads check L1 first, then L2, with automatic promotion of hot data to L1. Writes go to both tiers for consistency.
Example usage:
memCache := cache.NewMemoryCache() redisCache := cache.NewRedisCache(redisConfig) tiered := cache.NewTieredCache(memCache, redisCache)
func NewTieredCacheWithConfig ¶
func NewTieredCacheWithConfig(l1Cache, l2Cache Cache, config Config) *TieredCache
NewTieredCacheWithConfig creates a new tiered cache with custom configuration. This allows fine-tuning of cache behavior across both tiers while maintaining the performance benefits of multi-tier caching architecture.
func (*TieredCache) Clear ¶
func (tc *TieredCache) Clear(ctx context.Context) error
Clear removes all entries from both L1 and L2 caches
func (*TieredCache) Close ¶
func (tc *TieredCache) Close() error
Close closes both cache implementations
func (*TieredCache) Delete ¶
func (tc *TieredCache) Delete(ctx context.Context, key string) error
Delete removes a value from both L1 and L2 caches
func (*TieredCache) DeleteMulti ¶
func (tc *TieredCache) DeleteMulti(ctx context.Context, keys []string) error
DeleteMulti removes multiple values from both L1 and L2 caches
func (*TieredCache) GetL1Cache ¶
func (tc *TieredCache) GetL1Cache() Cache
GetL1Cache returns the L1 (fast) cache instance
func (*TieredCache) GetL2Cache ¶
func (tc *TieredCache) GetL2Cache() Cache
GetL2Cache returns the L2 (persistent) cache instance
func (*TieredCache) GetStats ¶
func (tc *TieredCache) GetStats() Stats
GetStats returns combined statistics from both cache levels
func (*TieredCache) GetTieredStats ¶
func (tc *TieredCache) GetTieredStats() map[string]Stats
GetTieredStats returns detailed statistics for each cache level
func (*TieredCache) InvalidateL1 ¶
func (tc *TieredCache) InvalidateL1(ctx context.Context, key string) error
InvalidateL1 removes a key from L1 cache while keeping it in L2
func (*TieredCache) Set ¶
func (tc *TieredCache) Set(ctx context.Context, key string, value interface{}, ttl time.Duration) error
Set stores a value in both L1 and L2 caches
func (*TieredCache) SetMulti ¶
func (tc *TieredCache) SetMulti(ctx context.Context, items map[string]interface{}, ttl time.Duration) error
SetMulti stores multiple values in both L1 and L2 caches
func (*TieredCache) WarmupL1 ¶
func (tc *TieredCache) WarmupL1(ctx context.Context, keys []string) error
WarmupL1 preloads L1 cache with values from L2 cache
func (*TieredCache) WithEventHandler ¶
func (tc *TieredCache) WithEventHandler(handler EventHandler) *TieredCache
WithEventHandler sets the event handler for cache events