### Install Gocache and Store Backends Source: https://context7.com/eko/gocache/llms.txt Install the core Gocache library and choose one or more store backends using go get. ```bash go get github.com/eko/gocache/lib/v4 # Choose one or more stores: go get github.com/eko/gocache/store/redis/v4 go get github.com/eko/gocache/store/bigcache/v4 go get github.com/eko/gocache/store/ristretto/v4 go get github.com/eko/gocache/store/go_cache/v4 go get github.com/eko/gocache/store/memcache/v4 go get github.com/eko/gocache/store/freecache/v4 go get github.com/eko/gocache/store/rueidis/v4 go get github.com/eko/gocache/store/rediscluster/v4 go get github.com/eko/gocache/store/hazelcast/v4 go get github.com/eko/gocache/store/pegasus/v4 ``` -------------------------------- ### Complete Integration Example with Ristretto, Metrics, and Loadable Cache Source: https://context7.com/eko/gocache/llms.txt This example showcases a full pipeline combining Ristretto in-memory cache, chained caches, Prometheus metrics, and a loadable cache for automatic data fetching on misses. It demonstrates setting up independent caches, chaining them, wrapping with metrics, and finally enabling auto-fetching with a custom loader function. Use this pattern for complex caching scenarios requiring multiple layers and automatic data backfilling. ```go package main import ( "context" "fmt" "time" ristretto "github.com/dgraph-io/ristretto/v2" "github.com/eko/gocache/lib/v4/cache" "github.com/eko/gocache/lib/v4/metrics" "github.com/eko/gocache/lib/v4/store" store_ristretto "github.com/eko/gocache/store/ristretto/v4" ) func main() { ctx := context.Background() newRistrettoClient := func() *ristretto.Cache[string, []byte] { c, err := ristretto.NewCache(&ristretto.Config[string, []byte]{ NumCounters: 1_000, MaxCost: 100_000_000, BufferItems: 64, }) if err != nil { panic(err) } return c } // Two independent in-memory caches memStore1 := store_ristretto.NewRistretto(newRistrettoClient(), store.WithExpiration(1*time.Minute)) memCache1 := cache.New[[]byte](memStore1) memStore2 := store_ristretto.NewRistretto(newRistrettoClient(), store.WithExpiration(1*time.Minute)) memCache2 := cache.New[[]byte](memStore2) // Chain: miss on cache1 → read cache2 → backfill cache1 chainCache := cache.NewChain[[]byte](memCache1, memCache2) // Metrics wrapper promMetrics := metrics.NewPrometheus("manifest-api") metricCache := cache.NewMetric[[]byte](promMetrics, chainCache) // Loadable: on miss in all caches, call the load function loadableCache := cache.NewLoadable[[]byte]( func(ctx context.Context, key any) ([]byte, []store.Option, error) { // Simulate fetching from a slow source (DB, API, etc.) data := []byte(fmt.Sprintf(`{"key":%q,"fetched":true}`, key)) return data, []store.Option{store.WithExpiration(5 * time.Minute)}, nil }, metricCache, ) defer loadableCache.Close() // Warm up cache1 _ = loadableCache.Set(ctx, "manifest:v1", []byte(`{"version":1}`))) time.Sleep(50 * time.Millisecond) // Evict from cache1; next Get will find it in cache2 and backfill cache1 _ = memCache1.Delete(ctx, "manifest:v1") time.Sleep(50 * time.Millisecond) value, err := loadableCache.Get(ctx, "manifest:v1") if err != nil { panic(err) } fmt.Println("Got:", string(value)) // Got: {"version":1} // Key not in any cache → load function invoked missing, err := loadableCache.Get(ctx, "manifest:v99") if err != nil { panic(err) } fmt.Println("Loaded:", string(missing)) // Loaded: {"key":"manifest:v99","fetched":true} } ``` -------------------------------- ### Gocache Store Options Examples Source: https://context7.com/eko/gocache/llms.txt Demonstrates how to use functional options to configure store-level defaults or override per-operation settings for expiration, tags, cost, and more. ```go import ( "time" "github.com/eko/gocache/lib/v4/store" ) // WithExpiration: sets key TTL (all stores that support it) expOpt := store.WithExpiration(30 * time.Second) // WithTags: associates string tags with a cache entry for group invalidation tagsOpt := store.WithTags([]string{"product", "catalog"}) // WithTagsTTL: sets the TTL of the tag index key (defaults to 720h) tagsTTLOpt := store.WithTagsTTL(24 * time.Hour) // WithCost: memory cost hint used by Ristretto costOpt := store.WithCost(5) // WithSynchronousSet: waits until Ristretto buffers are flushed syncOpt := store.WithSynchronousSet() // WithClientSideCaching: enables client-side caching TTL for Rueidis clientSideOpt := store.WithClientSideCaching(15 * time.Second) // Per-operation override example: err := cacheManager.Set(ctx, "my-key", "my-value", store.WithExpiration(10*time.Second), store.WithTags([]string{"user", "profile"}), ) ``` -------------------------------- ### Create and Use a Single-Store Cache Source: https://context7.com/eko/gocache/llms.txt Demonstrates creating a generic, type-safe cache with a single store (e.g., Redis). Supports setting, getting, getting with TTL, deleting, and clearing the cache. Per-operation TTL overrides are supported. ```go import ( "context" "fmt" "log" "time" "github.com/eko/gocache/lib/v4/cache" "github.com/eko/gocache/lib/v4/store" redis_store "github.com/eko/gocache/store/redis/v4" "github.com/redis/go-redis/v9" ) func main() { ctx := context.Background() redisStore := redis_store.NewRedis(redis.NewClient(&redis.Options{ Addr: "127.0.0.1:6379", }), store.WithExpiration(5*time.Minute)) cacheManager := cache.New[string](redisStore) // Set with per-operation TTL override if err := cacheManager.Set(ctx, "user:42", "Alice", store.WithExpiration(15*time.Second)); err != nil { log.Fatalf("set failed: %v", err) } // Get value, err := cacheManager.Get(ctx, "user:42") if err != nil { log.Fatalf("get failed: %v", err) } fmt.Println("Got:", value) // Got: Alice // GetWithTTL value, ttl, err := cacheManager.GetWithTTL(ctx, "user:42") if err != nil { log.Fatalf("get with TTL failed: %v", err) } fmt.Printf("Value: %s, TTL remaining: %s\n", value, ttl) // Delete if err := cacheManager.Delete(ctx, "user:42"); err != nil { log.Fatalf("delete failed: %v", err) } // Clear entire cache if err := cacheManager.Clear(ctx); err != nil { log.Fatalf("clear failed: %v", err) } } ``` -------------------------------- ### Install Gocache Core Library Source: https://github.com/eko/gocache/blob/master/README.md Import the latest version of the gocache library into your Go project. ```go go get github.com/eko/gocache/lib/v4 ``` -------------------------------- ### Install Gocache Store Modules Source: https://github.com/eko/gocache/blob/master/README.md Import specific store modules you intend to use with Gocache. ```go go get github.com/eko/gocache/store/bigcache/v4 go get github.com/eko/gocache/store/freecache/v4 go get github.com/eko/gocache/store/go_cache/v4 go get github.com/eko/gocache/store/hazelcast/v4 go get github.com/eko/gocache/store/memcache/v4 go get github.com/eko/gocache/store/pegasus/v4 go get github.com/eko/gocache/store/redis/v4 go get github.com/eko/gocache/store/rediscluster/v4 go get github.com/eko/gocache/store/rueidis/v4 go get github.com/eko/gocache/store/ristretto/v4 ``` -------------------------------- ### Set Cache Item with Expiration Time Source: https://github.com/eko/gocache/blob/master/README.md Demonstrates setting a cache item with a specific expiration time using `store.WithExpiration`. This example also shows basic Get and Set operations with a Redis store. Requires a cache store. ```go package main import ( "fmt" "log" "time" "github.com/eko/gocache/lib/v4/cache" "github.com/eko/gocache/lib/v4/store" "github.com/redis/go-redis/v9" ) func main() { redisStore := redis_store.NewRedis(redis.NewClient(&redis.Options{ Addr: "127.0.0.1:6379", }), nil) cacheManager := cache.New[string](redisStore) err := cacheManager.Set(ctx, "my-key", "my-value", store.WithExpiration(15*time.Second)) if err != nil { panic(err) } key := "my-key" value, err := cacheManager.Get(ctx, key) if err != nil { log.Fatalf("unable to get cache key '%s' from the cache: %v", key, err) } fmt.Printf("%#+v\n", value) } ``` -------------------------------- ### Set and Get Data with Memcache Source: https://github.com/eko/gocache/blob/master/README.md Set a key-value pair in the cache, overriding the default expiration, and then retrieve the value. ```go err := cacheManager.Set(ctx, "my-key", []byte("my-value"), store.WithExpiration(15*time.Second), // Override default value of 10 seconds defined in the store ) if err != nil { panic(err) } value := cacheManager.Get(ctx, "my-key") ``` -------------------------------- ### Pegasus Distributed Store Source: https://context7.com/eko/gocache/llms.txt Shows how to set up and use the Apache Pegasus distributed store with GoCache. Includes an example of setting and retrieving data. ```APIDOC ## pegasus_store.NewPegasus ### Description Initializes a new Apache Pegasus distributed store for GoCache. This enables using Pegasus as a distributed cache. ### Usage ```go import ( "context" "fmt" "time" "github.com/eko/gocache/lib/v4/cache" "github.com/eko/gocache/lib/v4/store" pegasus_store "github.com/eko/gocache/store/pegasus/v4" ) func main() { ctx := context.Background() // Initialize Pegasus store with meta-server addresses pegStore, err := pegasus_store.NewPegasus(&store.OptionsPegasus{ MetaServers: []string{"127.0.0.1:34601", "127.0.0.1:34602", "127.0.0.1:34603"}, }) if err != nil { fmt.Println("store init failed:", err) return } c := cache.New[string](pegStore) _ = c.Set(ctx, "metric:cpu", "87.3", store.WithExpiration(10*time.Second)) val, _ := c.Get(ctx, "metric:cpu") fmt.Println("CPU usage:", val) // CPU usage: 87.3 } ``` ### Parameters - `options` (*store.OptionsPegasus) - `MetaServers` ([]string) - Required - List of Pegasus meta-server addresses. ### Response - `store.StoreInterface` ``` -------------------------------- ### Hazelcast Distributed Store Source: https://context7.com/eko/gocache/llms.txt Demonstrates how to initialize and use the Hazelcast distributed store with GoCache. It shows setting and getting values with expiration. ```APIDOC ## hazelcast_store.NewHazelcast ### Description Initializes a new Hazelcast distributed store for GoCache. This allows you to use Hazelcast as a distributed cache backend. ### Usage ```go import ( "context" "log" "time" hz "github.com/hazelcast/hazelcast-go-client" "github.com/eko/gocache/lib/v4/cache" "github.com/eko/gocache/lib/v4/store" hazelcast_store "github.com/eko/gocache/store/hazelcast/v4" ) func main() { ctx := context.Background() // Initialize Hazelcast client hzClient, err := hz.StartNewClient(ctx) if err != nil { log.Fatal(err) } defer hzClient.Shutdown(ctx) // Get Hazelcast map hzMap, err := hzClient.GetMap(ctx, "gocache") if err != nil { log.Fatal(err) } // Create Hazelcast store hzStore := hazelcast_store.NewHazelcast(hzMap) c := cache.New[string](hzStore) // Set a value with expiration _ = c.Set(ctx, "order:99", "pending", store.WithExpiration(15*time.Second)) // Get a value val, err := c.Get(ctx, "order:99") if err != nil { log.Fatal(err) } fmt.Println("Order status:", val) // Order status: pending } ``` ### Parameters - `hzMap` (*interface{}) - `options` (*store.Options) ### Response - `store.StoreInterface` ``` -------------------------------- ### Implement Custom Store Interface Source: https://github.com/eko/gocache/blob/master/README.md Implement this interface to create a custom data store. It includes methods for Get, GetWithTTL, Set, Delete, Invalidate, Clear, and GetType. ```go type StoreInterface interface { Get(ctx context.Context, key any) (any, error) GetWithTTL(ctx context.Context, key any) (any, time.Duration, error) Set(ctx context.Context, key any, value any, options ...Option) error Delete(ctx context.Context, key any) error Invalidate(ctx context.Context, options ...InvalidateOption) error Clear(ctx context.Context) error GetType() string } ``` -------------------------------- ### Set and Get Data with Bigcache Source: https://github.com/eko/gocache/blob/master/README.md Store a byte slice value in the Bigcache and then retrieve it using its key. ```go err := cacheManager.Set(ctx, "my-key", []byte("my-value")) if err != nil { panic(err) } value := cacheManager.Get(ctx, "my-key") ``` -------------------------------- ### Use Marshaler for Automatic Struct Serialization Source: https://context7.com/eko/gocache/llms.txt This example demonstrates using the Marshaler to automatically serialize Go structs to msgpack bytes for storage and deserialize them on retrieval. It requires a compatible cache store like Redis. ```go import ( "context" "fmt" "log" "time" "github.com/eko/gocache/lib/v4/cache" "github.com/eko/gocache/lib/v4/marshaler" "github.com/eko/gocache/lib/v4/store" redis_store "github.com/eko/gocache/store/redis/v4" "github.com/redis/go-redis/v9" ) type BookQuery struct { Slug string } func (b BookQuery) GetCacheKey() string { return "book:" + b.Slug } type Book struct { ID int Name string Slug string Price float64 } func main() { ctx := context.Background() redisStore := redis_store.NewRedis(redis.NewClient(&redis.Options{Addr: "127.0.0.1:6379"})) m := marshaler.New(cache.New[any](redisStore)) key := BookQuery{Slug: "the-go-programming-language"} value := Book{ID: 1, Name: "The Go Programming Language", Slug: "the-go-programming-language", Price: 39.99} // Set marshals Book → msgpack bytes → Redis if err := m.Set(ctx, key, value, store.WithExpiration(1*time.Hour)); err != nil { log.Fatal("set failed:", err) } // Get unmarshals Redis bytes → *Book raw, err := m.Get(ctx, key, new(Book)) if err != nil { log.Fatal("get failed:", err) } book := raw.(*Book) fmt.Printf("Book: %s (%.2f)\n", book.Name, book.Price) // Book: The Go Programming Language (39.99) // Tag-based invalidation _ = m.Set(ctx, key, value, store.WithTags([]string{"books"})) _ = m.Invalidate(ctx, store.WithInvalidateTags([]string{"books"})) _, err = m.Get(ctx, key, new(Book)) if err != nil { fmt.Println("After invalidation, key not found:", err) } _ = m.Delete(ctx, key) _ = m.Clear(ctx) } ``` -------------------------------- ### Implement Custom Cache Interface Source: https://github.com/eko/gocache/blob/master/README.md Implement this interface to create your own cache logic. It defines core cache operations like Get, Set, Delete, Invalidate, Clear, and GetType. ```go type CacheInterface[T any] interface { Get(ctx context.Context, key any) (T, error) Set(ctx context.Context, key any, object T, options ...store.Option) error Delete(ctx context.Context, key any) error Invalidate(ctx context.Context, options ...store.InvalidateOption) error Clear(ctx context.Context) error GetType() string } ``` -------------------------------- ### Initialize and Use Ristretto Store Source: https://context7.com/eko/gocache/llms.txt Shows how to initialize and use the Ristretto store, which supports generic key and value types, per-key TTL, and cost-based eviction. ```go import ( "context" "fmt" "time" ristretto "github.com/dgraph-io/ristretto/v2" "github.com/eko/gocache/lib/v4/cache" "github.com/eko/gocache/lib/v4/store" ristretto_store "github.com/eko/gocache/store/ristretto/v4" ) func main() { ctx := context.Background() client, err := ristretto.NewCache(&ristretto.Config[string, string]{ NumCounters: 1_000, MaxCost: 100, BufferItems: 64, }) if err != nil { panic(err) } rStore := ristretto_store.NewRistretto(client) c := cache.New[string](rStore) _ = c.Set(ctx, "token:xyz", "bearer-abc", store.WithExpiration(10*time.Minute), store.WithCost(1), store.WithSynchronousSet(), // wait for write to be visible ) val, err := c.Get(ctx, "token:xyz") if err != nil { fmt.Println("miss:", err) return } fmt.Println("Got:", val) // Got: bearer-abc } ``` -------------------------------- ### Initialize and Use Freecache Store Source: https://context7.com/eko/gocache/llms.txt Demonstrates initializing and using the Freecache store, an in-memory cache with a specified size limit. ```go import ( "context" "fmt" "time" "github.com/coocood/freecache" "github.com/eko/gocache/lib/v4/cache" "github.com/eko/gocache/lib/v4/store" freecache_store "github.com/eko/gocache/store/freecache/v4" ) func main() { ctx := context.Background() // 10 MB cache fcStore := freecache_store.NewFreecache(freecache.NewCache(10*1024*1024), store.WithExpiration(10*time.Second)) c := cache.New[[]byte](fcStore) _ = c.Set(ctx, "rate:ip:1.2.3.4", []byte("42")) val, err := c.Get(ctx, "rate:ip:1.2.3.4") if err == nil { fmt.Println("Count:", string(val)) // Count: 42 } } ``` -------------------------------- ### Initialize Bigcache Store and Cache Manager Source: https://github.com/eko/gocache/blob/master/README.md Create a Bigcache client with default configuration and initialize a Bigcache store, then set up the cache manager. ```go bigcacheClient, _ := bigcache.NewBigCache(bigcache.DefaultConfig(5 * time.Minute)) bigcacheStore := bigcache_store.NewBigcache(bigcacheClient) cacheManager := cache.New[[]byte](bigcacheStore) ``` -------------------------------- ### Initialize and Use Memcache Store Source: https://context7.com/eko/gocache/llms.txt Demonstrates the initialization and usage of the Memcache store. It allows overriding the default expiration set during store initialization. ```go import ( "time" "github.com/bradfitz/gomemcache/memcache" "github.com/eko/gocache/lib/v4/cache" "github.com/eko/gocache/lib/v4/store" memcache_store "github.com/eko/gocache/store/memcache/v4" ) func main() { ctx := context.Background() mcStore := memcache_store.NewMemcache( memcache.New("10.0.0.1:11211", "10.0.0.2:11211"), store.WithExpiration(10*time.Second), ) c := cache.New[[]byte](mcStore) _ = c.Set(ctx, "page:home", []byte("..."), store.WithExpiration(30*time.Second)) // override default val, err := c.Get(ctx, "page:home") if err == nil { _ = val // use []byte value } } ``` -------------------------------- ### Initialize Chained Cache (Ristretto + Redis) Source: https://github.com/eko/gocache/blob/master/README.md Demonstrates initializing a chained cache with Ristretto (memory) as the primary store and Redis as a fallback. Data is put back into previous caches if found in later ones. ```go // Initialize Ristretto cache and Redis client ristrettoCache, err := ristretto.NewCache(&ristretto.Config[string, string]{ NumCounters: 1000, MaxCost: 100, BufferItems: 64, }) if err != nil { panic(err) } redisClient := redis.NewClient(&redis.Options{Addr: "127.0.0.1:6379"}) // Initialize stores ristrettoStore := ristretto_store.NewRistretto(ristrettoCache) redisStore := redis_store.NewRedis(redisClient, store.WithExpiration(5*time.Second)) // Initialize chained cache cacheManager := cache.NewChain[any]( cache.New[any](ristrettoStore), cache.New[any](redisStore), ) // ... Then, do what you want with your cache ``` -------------------------------- ### Initialize Pegasus Store and Cache Source: https://context7.com/eko/gocache/llms.txt Shows how to set up an Apache Pegasus distributed store and integrate it with GoCache. Requires a running Pegasus cluster. ```go import ( "context" "fmt" "time" "github.com/eko/gocache/lib/v4/cache" "github.com/eko/gocache/lib/v4/store" pegasus_store "github.com/eko/gocache/store/pegasus/v4" ) func main() { ctx := context.Background() pegStore, err := pegasus_store.NewPegasus(&store.OptionsPegasus{ MetaServers: []string{"127.0.0.1:34601", "127.0.0.1:34602", "127.0.0.1:34603"}, }) if err != nil { fmt.Println("store init failed:", err) return } c := cache.New[string](pegStore) _ = c.Set(ctx, "metric:cpu", "87.3", store.WithExpiration(10*time.Second)) val, _ := c.Get(ctx, "metric:cpu") fmt.Println("CPU usage:", val) // CPU usage: 87.3 } ``` -------------------------------- ### Initialize Freecache Source: https://github.com/eko/gocache/blob/master/README.md Demonstrates initializing a Freecache store and a GoCache manager. Freecache is a fast, in-memory cache library. ```go freecacheStore := freecache_store.NewFreecache(freecache.NewCache(1000), store.WithExpiration(10 * time.Second)) cacheManager := cache.New[[]byte](freecacheStore) err := cacheManager.Set(ctx, "by-key", []byte("my-value"), opts) if err != nil { panic(err) } value := cacheManager.Get(ctx, "my-key") ``` -------------------------------- ### Create and Use a Chained Multi-Layer Cache Source: https://context7.com/eko/gocache/llms.txt Illustrates setting up a cache that uses multiple layers (e.g., Ristretto for local in-memory and Redis for persistent storage). Cache misses in earlier layers trigger reads from subsequent layers and backfill into preceding ones. ```go import ( "context" "fmt" "time" ristretto "github.com/dgraph-io/ristretto/v2" "github.com/eko/gocache/lib/v4/cache" "github.com/eko/gocache/lib/v4/store" ristretto_store "github.com/eko/gocache/store/ristretto/v4" redis_store "github.com/eko/gocache/store/redis/v4" "github.com/redis/go-redis/v9" ) func main() { ctx := context.Background() // Layer 1: in-process Ristretto (fast, local) ristrettoClient, _ := ristretto.NewCache(&ristretto.Config[string, string]{ NumCounters: 1_000, MaxCost: 100, BufferItems: 64, }) memStore := ristretto_store.NewRistretto(ristrettoClient, store.WithExpiration(1*time.Minute)) memCache := cache.New[string](memStore) // Layer 2: Redis (shared, persistent) redisStore := redis_store.NewRedis(redis.NewClient(&redis.Options{Addr: "127.0.0.1:6379"}), store.WithExpiration(10*time.Minute)) redisCache := cache.New[string](redisStore) // Chain: Ristretto first, then Redis as fallback chainCache := cache.NewChain[string](memCache, redisCache) // Set populates all layers _ = chainCache.Set(ctx, "session:abc", "user-data", store.WithExpiration(5*time.Minute)) // Get checks Ristretto first; on miss it reads Redis and backfills Ristretto value, err := chainCache.Get(ctx, "session:abc") if err != nil { fmt.Println("cache miss:", err) return } fmt.Println("Got:", value) // Got: user-data // Inspect underlying caches for _, c := range chainCache.GetCaches() { fmt.Println("layer type:", c.GetType()) } // Delete removes from all layers _ = chainCache.Delete(ctx, "session:abc") } ``` -------------------------------- ### Initialize Memcache Store and Cache Manager Source: https://github.com/eko/gocache/blob/master/README.md Instantiate a Memcache store with specific client configurations and expiration, then create a cache manager. ```go memcacheStore := memcache_store.NewMemcache( memcache.New("10.0.0.1:11211", "10.0.0.2:11211", "10.0.0.3:11212"), store.WithExpiration(10*time.Second), ) cacheManager := cache.New[[]byte](memcacheStore) ``` -------------------------------- ### Initialize Ristretto Memory Cache Source: https://github.com/eko/gocache/blob/master/README.md Demonstrates initializing a Ristretto cache store and a GoCache manager. Use this for in-memory caching with Ristretto. ```go import ( "github.com/dgraph-io/ristretto" "github.com/eko/gocache/lib/v4/cache" "github.com/eko/gocache/lib/v4/store" ristretto_store "github.com/eko/gocache/store/ristretto/v4" ) rristrettoCache, err := ristretto.NewCache(&ristretto.Config[string, string]{ NumCounters: 1000, MaxCost: 100, BufferItems: 64, }) if err != nil { panic(err) } ristrettoStore := ristretto_store.NewRistretto(ristrettoCache) cacheManager := cache.New[string](ristrettoStore) err := cacheManager.Set(ctx, "my-key", "my-value", store.WithCost(2)) if err != nil { panic(err) } value := cacheManager.Get(ctx, "my-key") cacheManager.Delete(ctx, "my-key") ``` -------------------------------- ### Initialize Loadable Cache with Custom Data Loading Source: https://github.com/eko/gocache/blob/master/README.md Demonstrates how to create a loadable cache that automatically fetches and stores data when a key is not found. Requires a custom load function and a cache store. ```go type Book struct { ID string Name string } // Initialize Redis client and store redisClient := redis.NewClient(&redis.Options{Addr: "127.0.0.1:6379"}) redisStore := redis_store.NewRedis(redisClient) // Initialize a load function that loads your data from a custom source loadFunction := func(ctx context.Context, key any) (*Book, error) { // ... retrieve value from available source return &Book{ID: 1, Name: "My test amazing book"}, nil } // Initialize loadable cache cacheManager := cache.NewLoadable[*Book]( loadFunction, cache.New[*Book](redisStore), ) // ... Then, you can get your data and your function will automatically put them in cache(s) ``` -------------------------------- ### Initialize Redis Cache Source: https://github.com/eko/gocache/blob/master/README.md Demonstrates initializing a Redis cache store and a GoCache manager. Use this for distributed caching with Redis. ```go redisStore := redis_store.NewRedis(redis.NewClient(&redis.Options{ Addr: "127.0.0.1:6379", })) cacheManager := cache.New[string](redisStore) err := cacheManager.Set(ctx, "my-key", "my-value", store.WithExpiration(15*time.Second)) if err != nil { panic(err) } value, err := cacheManager.Get(ctx, "my-key") switch err { case nil: fmt.Printf("Get the key '%s' from the redis cache. Result: %s", "my-key", value) case redis.Nil: fmt.Printf("Failed to find the key '%s' from the redis cache.", "my-key") default: fmt.Printf("Failed to get the value from the redis cache with key '%s': %v", "my-key", err) } ``` -------------------------------- ### Initialize Hazelcast Cache Source: https://github.com/eko/gocache/blob/master/README.md Demonstrates initializing a Hazelcast cache store and a GoCache manager. Hazelcast provides distributed data structures and caching. ```go hzClient, err := hazelcast.StartNewClient(ctx) if err != nil { log.Fatalf("Failed to start client: %v", err) } hzMap, err := hzClient.GetMap(ctx, "gocache") if err != nil { b.Fatalf("Failed to get map: %v", err) } hazelcastStore := hazelcast_store.NewHazelcast(hzMap) cacheManager := cache.New[string](hazelcastStore) err := cacheManager.Set(ctx, "my-key", "my-value", store.WithExpiration(15*time.Second)) if err != nil { panic(err) } value, err := cacheManager.Get(ctx, "my-key") if err != nil { panic(err) } fmt.Printf("Get the key '%s' from the hazelcast cache. Result: %s", "my-key", value) ``` -------------------------------- ### Initialize Hazelcast Store and Cache Source: https://context7.com/eko/gocache/llms.txt Demonstrates how to initialize a Hazelcast distributed store and use it with the GoCache client. Ensure Hazelcast client is running and accessible. ```go import ( "context" "fmt" "log" "time" hz "github.com/hazelcast/hazelcast-go-client" "github.com/eko/gocache/lib/v4/cache" "github.com/eko/gocache/lib/v4/store" hazelcast_store "github.com/eko/gocache/store/hazelcast/v4" ) func main() { ctx := context.Background() hzClient, err := hz.StartNewClient(ctx) if err != nil { log.Fatal(err) } defer hzClient.Shutdown(ctx) hzMap, err := hzClient.GetMap(ctx, "gocache") if err != nil { log.Fatal(err) } hzStore := hazelcast_store.NewHazelcast(hzMap) c := cache.New[string](hzStore) _ = c.Set(ctx, "order:99", "pending", store.WithExpiration(15*time.Second)) val, err := c.Get(ctx, "order:99") if err != nil { log.Fatal(err) } fmt.Println("Order status:", val) // Order status: pending } ``` -------------------------------- ### Run Unit Tests Source: https://github.com/eko/gocache/blob/master/README.md Execute the test suite for the project using the 'make test' command. ```bash $ make test # run unit test ``` -------------------------------- ### Initialize Metric Cache with Prometheus Provider Source: https://github.com/eko/gocache/blob/master/README.md Shows how to set up a cache that records metrics using a Prometheus provider. This is useful for monitoring cache performance. Requires a metrics provider and a cache store. ```go // Initialize Redis client and store redisClient := redis.NewClient(&redis.Options{Addr: "127.0.0.1:6379"}) redisStore := redis_store.NewRedis(redisClient) // Initializes Prometheus metrics service promMetrics := metrics.NewPrometheus("my-test-app") // Initialize metric cache cacheManager := cache.NewMetric[any]( promMetrics, cache.New[any](redisStore), ) // ... Then, you can get your data and metrics will be observed by Prometheus ``` -------------------------------- ### Initialize Go-cache Memory Cache Source: https://github.com/eko/gocache/blob/master/README.md Demonstrates initializing a Go-cache store and a GoCache manager. Suitable for simple in-memory caching with expiration. ```go gocacheClient := gocache.New(5*time.Minute, 10*time.Minute) gocacheStore := gocache_store.NewGoCache(gocacheClient) cacheManager := cache.New[[]byte](gocacheStore) err := cacheManager.Set(ctx, "my-key", []byte("my-value")) if err != nil { panic(err) } value, err := cacheManager.Get(ctx, "my-key") if err != nil { panic(err) } fmt.Printf("%s", value) ``` -------------------------------- ### Initialize Pegasus Cache Source: https://github.com/eko/gocache/blob/master/README.md Demonstrates initializing a Pegasus cache store and a GoCache manager. Pegasus is a distributed key-value store. ```go pegasusStore, err := pegasus_store.NewPegasus(&store.OptionsPegasus{ MetaServers: []string{"127.0.0.1:34601", "127.0.0.1:34602", "127.0.0.1:34603"}, }) if err != nil { fmt.Println(err) return } cacheManager := cache.New[string](pegasusStore) err = cacheManager.Set(ctx, "my-key", "my-value", store.WithExpiration(10 * time.Second)) if err != nil { panic(err) } value, _ := cacheManager.Get(ctx, "my-key") ``` -------------------------------- ### Initialize and Use Bigcache Store Source: https://context7.com/eko/gocache/llms.txt Demonstrates how to initialize and use the Bigcache store with GoCache. Bigcache stores only []byte values and sets TTL at the client level. ```go import ( "context" "fmt" "time" bigcache "github.com/allegro/bigcache/v3" "github.com/eko/gocache/lib/v4/cache" bigcache_store "github.com/eko/gocache/store/bigcache/v4" ) func main() { ctx := context.Background() client, err := bigcache.NewBigCache(bigcache.DefaultConfig(5 * time.Minute)) if err != nil { panic(err) } bcStore := bigcache_store.NewBigcache(client) c := cache.New[[]byte](bcStore) _ = c.Set(ctx, "blob:1", []byte(`{"id":1,"name":"example"}`)) val, err := c.Get(ctx, "blob:1") if err != nil { panic(err) } fmt.Println(string(val)) // {"id":1,"name":"example"} _ = c.Clear(ctx) // calls bigcache Reset() } ``` -------------------------------- ### Import Gocache and Redis Store Source: https://github.com/eko/gocache/blob/master/README.md Import the core cache library and the Redis store for use in your application. ```go import ( "github.com/eko/gocache/lib/v4/cache" "github.com/eko/gocache/store/redis/v4" ) ``` -------------------------------- ### Initialize and Use Rueidis Store with Client-Side Caching Source: https://context7.com/eko/gocache/llms.txt Shows how to initialize the Rueidis store for Redis with support for client-side caching (server-assisted invalidation). ```go import ( "context" "log" "time" "github.com/redis/rueidis" "github.com/eko/gocache/lib/v4/cache" "github.com/eko/gocache/lib/v4/store" rueidis_store "github.com/eko/gocache/store/rueidis/v4" ) func main() { ctx := context.Background() client, err := rueidis.NewClient(rueidis.ClientOption{ InitAddress: []string{"127.0.0.1:6379"}, }) if err != nil { panic(err) } defer client.Close() c := cache.New[string](rueidis_store.NewRueidis( client, store.WithExpiration(15*time.Second), store.WithClientSideCaching(15*time.Second), // enable CSC )) if err = c.Set(ctx, "config:feature-flags", `{"darkMode":true}`); err != nil { panic(err) } val, err := c.Get(ctx, "config:feature-flags") if err != nil { log.Fatalf("get failed: %v", err) } log.Println("Got:", val) } ``` -------------------------------- ### Handle Cache Misses with store.NotFound Source: https://context7.com/eko/gocache/llms.txt All stores return a `*store.NotFound` error for missing keys. Use `errors.Is` to differentiate cache misses from other potential errors. ```go import ( "context" "errors" "fmt" "github.com/eko/gocache/lib/v4/cache" "github.com/eko/gocache/lib/v4/store" redis_store "github.com/eko/gocache/store/redis/v4" "github.com/redis/go-redis/v9" ) func getUser(ctx context.Context, c cache.CacheInterface[string], id string) (string, error) { val, err := c.Get(ctx, "user:"+id) if err != nil { if errors.Is(err, &store.NotFound{}) { return "", fmt.Errorf("user %s not cached", id) } return "", fmt.Errorf("cache error: %w", err) } return val, nil } func main() { ctx := context.Background() redisStore := redis_store.NewRedis(redis.NewClient(&redis.Options{Addr: "127.0.0.1:6379"})) c := cache.New[string](redisStore) user, err := getUser(ctx, c, "99") if err != nil { fmt.Println(err) // user 99 not cached } else { fmt.Println("User:", user) } } ``` -------------------------------- ### Redis Store Backend Source: https://context7.com/eko/gocache/llms.txt Initializes a Redis store with a default expiration time. Demonstrates setting and retrieving a string value with a specific expiration, and handling potential errors including cache misses. ```go import ( "context" "fmt" "time" "github.com/eko/gocache/lib/v4/cache" "github.com/eko/gocache/lib/v4/store" redis_store "github.com/eko/gocache/store/redis/v4" "github.com/redis/go-redis/v9" ) func main() { ctx := context.Background() redisStore := redis_store.NewRedis( redis.NewClient(&redis.Options{Addr: "127.0.0.1:6379"}), store.WithExpiration(5*time.Minute), // default TTL ) c := cache.New[string](redisStore) _ = c.Set(ctx, "greeting", "hello", store.WithExpiration(15*time.Second)) val, err := c.Get(ctx, "greeting") switch { case err == nil: fmt.Println("Got:", val) case errors.Is(err, &store.NotFound{}): fmt.Println("Key not found") default: fmt.Println("Error:", err) } } ``` -------------------------------- ### Generate Mocks with Mockgen Source: https://github.com/eko/gocache/blob/master/README.md Run this command to generate mocks for your Go code using the mockgen library. ```bash $ make mocks ``` -------------------------------- ### Initialize Redis Client-Side Caching with Rueidis Source: https://github.com/eko/gocache/blob/master/README.md Demonstrates initializing a Redis cache with client-side caching enabled using the rueidis library. This can improve performance by caching data on the client. ```go client, err := rueidis.NewClient(rueidis.ClientOption{InitAddress: []string{"127.0.0.1:6379"}}) if err != nil { panic(err) } cacheManager := cache.New[string](rueidis_store.NewRueidis( client, store.WithExpiration(15*time.Second), store.WithClientSideCaching(15*time.Second))) if err = cacheManager.Set(ctx, "my-key", "my-value"); err != nil { panic(err) } value, err := cacheManager.Get(ctx, "my-key") if err != nil { log.Fatalf("Failed to get the value from the redis cache with key '%s': %v", "my-key", err) } log.Printf("Get the key '%s' from the redis cache. Result: %s", "my-key", value) ``` -------------------------------- ### Implement Custom Cache Key Generator Source: https://github.com/eko/gocache/blob/master/README.md Implement this interface to define a custom strategy for generating cache keys. ```go type CacheKeyGenerator interface { GetCacheKey() string } ``` -------------------------------- ### Metrics-Observing Cache Wrapper Source: https://context7.com/eko/gocache/llms.txt Wraps any cache to record statistics like hits, misses, and sets using a provided MetricsInterface. Supports Prometheus integration out-of-the-box. Metrics include hit_count, miss_count, set_success, set_error, delete_success, delete_error, invalidate_success, and invalidate_error. ```go import ( "context" "time" "github.com/eko/gocache/lib/v4/cache" "github.com/eko/gocache/lib/v4/metrics" "github.com/eko/gocache/lib/v4/store" redis_store "github.com/eko/gocache/store/redis/v4" "github.com/redis/go-redis/v9" ) func main() { ctx := context.Background() redisStore := redis_store.NewRedis(redis.NewClient(&redis.Options{Addr: "127.0.0.1:6379"})) // Prometheus metrics for a service named "my-api" promMetrics := metrics.NewPrometheus("my-api") // Optional customization: // promMetrics := metrics.NewPrometheus("my-api", // metrics.WithNamespace("myapp"), // metrics.WithAttributesNamespace("lbl"), // metrics.WithRegisterer(prometheus.NewRegistry()), // ) metricCache := cache.NewMetric[string]( promMetrics, cache.New[string](redisStore), ) _ = metricCache.Set(ctx, "key1", "value1", store.WithExpiration(30*time.Second)) _, _ = metricCache.Get(ctx, "key1") // increments hit_count _, _ = metricCache.Get(ctx, "missing") // increments miss_count // Prometheus exposes: cache_collector{service="my-api", store="redis", metric="hit_count"} // Metrics: hit_count, miss_count, set_success, set_error, // delete_success, delete_error, invalidate_success, invalidate_error } ``` -------------------------------- ### Delete and Clear Cache with Memcache Source: https://github.com/eko/gocache/blob/master/README.md Remove a specific key from the cache or clear all entries. ```go cacheManager.Delete(ctx, "my-key") cacheManager.Clear(ctx) // Clears the entire cache, in case you want to flush all cache ```