gocache

repository·master·Indexed 25 days ago

https://github.com/eko/gocache

An extendable Go caching library providing a unified interface for various stores including Redis, Memcache, Bigcache, Freecache, Go-cache, Hazelcast, Pegasus, Rueidis, and Ristretto. It supports advanced features such as cache chaining, loadable caches with singleflight to prevent stampedes, metrics collection via Prometheus, and tag-based invalidation.

Tokens
10.3K
Snippets
21
Records
101
Agent score
83%

What's inside eko/gocache

  1. Invalidate cache items using tags

    master

    You can attach tags to cached items using store.WithTags([]string{...}) during the Set operation. This allows you to invalidate groups of related items simultaneously using marshal.Invalidate with store.WithInvalidateTags([]string{...}).

    // Set an item with a tag
    err = marshal.Set(ctx, key, value, store.WithTags([]string{"book"}))
    
    // Remove all items that have the "book" tag
    err := marshal.Invalidate(ctx, store.WithInvalidateTags([]string{"book"}))
  2. Use a marshaler wrapper for complex objects

    master

    For stores that only support string or byte slices (like Redis), use the marshaler service. It automatically handles the marshaling and unmarshaling of Go structs.

    When calling .Get(), you must provide a pointer to the target struct as the third argument to unmarshal the data into.

    // Initializes marshaler
    marshal := marshaler.New(cacheManager)
    
    key := BookQuery{Slug: "my-test-amazing-book"}
    value := Book{ID: 1, Name: "My test amazing book", Slug: "my-test-amazing-book"}
    
    // Set with marshaling
    err = marshal.Set(ctx, key, value)
    
    // Get with unmarshaling into a specific type
    returnedValue, err := marshal.Get(ctx, key, new(Book))
  3. Initialize a simple cache with various stores

    master

    Gocache supports multiple storage backends. You can instantiate a cache manager by passing a specific store to cache.New[T](store).

    Commonly used stores include:

    • Memcache: Using memcache_store.NewMemcache.
    • Bigcache: Using bigcache_store.NewBigcache.
    • Ristretto: Using ristretto_store.NewRistretto.
    • Go-cache: Using gocache_store.NewGoCache.
    • Redis: Using redis_store.NewRedis.
    • Rueidis (Redis Client-Side Caching): Using rueidis_store.NewRueidis.
    • Freecache: Using freecache_store.NewFreecache.
    • Pegasus: Using pegasus_store.NewPegasus.
    • Hazelcast: Using hazelcast_store.NewHazelcast.

    When using Set, you can override the store's default expiration using store.WithExpiration(duration).

    // Example: Memcache
    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)
    err := cacheManager.Set(ctx, "my-key", []byte("my-value"),
    	store.WithExpiration(15*time.Second), // Override default
    )
  4. Import gocache in your Go project

    master

    When using gocache, import the core cache package and your chosen store package. For example, to use Redis:

    import (
    	"github.com/eko/gocache/lib/v4/cache"
    	"github.com/eko/gocache/store/redis/v4"
    )
  5. Implement a chained cache

    master

    A Chain cache allows you to layer multiple caches. When a key is requested, it checks the caches in the order they were provided. If a value is found in a later cache (e.g., Redis), it is automatically set back into the preceding caches (e.g., Ristretto/Memory) in the background.

    Note: A Chain cache owns a goroutine for background updates. You must call Close() to release the goroutine and ensure pending values are set.

    // 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),
    )
    defer cacheManager.Close()
  6. Implement a loadable cache

    master

    A Loadable cache uses a provided loadFunction to retrieve data if it is missing from the cache. Once the function retrieves the data, the cache automatically populates the underlying store(s) with the result.

    Note: Like Chain, Loadable caches run background processes for updates; call Close() to clean up.

    You can wrap a Chain cache inside a Loadable cache to ensure data is backfilled across all layers of the chain.

    // Initialize a load function
    loadFunction := func(ctx context.Context, key any) (*Book, error) {
        // ... retrieve value from custom source
        return &Book{ID: 1, Name: "My test amazing book"}, nil
    }
    
    // Initialize loadable cache
    cacheManager := cache.NewLoadable[*Book](
    	loadFunction,
    	cache.New[*Book](redisStore),
    )
    defer cacheManager.Close()
  7. Use a metric cache for statistics

    master

    You can wrap a cache with cache.NewMetric[T] to record cache hits, misses, and other statistics using a metric provider (e.g., Prometheus).

    // Initializes Prometheus metrics service
    promMetrics := metrics.NewPrometheus("my-test-app")
    
    // Initialize metric cache
    cacheManager := cache.NewMetric[any](
    	promMetrics,
    	cache.New[any](redisStore),
    )
  8. Configure OptionsPegasus

    master

    The OptionsPegasus struct defines the connection and table settings for the Pegasus store. It embeds lib_store.Options for standard cache configuration.

    Key fields:

    • MetaServers: A slice of strings containing the Pegasus meta server addresses (Required).
    • TableName: The name of the Pegasus table to use. Defaults to gocache_pegasus if empty.
    • TablePartitionNum: Number of partitions for the table. Defaults to 4.
    • TableScanNum: The batch size used during scanning operations (like Clear). Defaults to 100.
  9. Available gocache stores

    master

    Gocache supports various built-in stores. You can install them by running go get for the corresponding package path. Available stores include:

    • github.com/eko/gocache/store/bigcache/v4 (bigcache)
    • github.com/eko/gocache/store/freecache/v4 (freecache)
    • github.com/eko/gocache/store/go_cache/v4 (go-cache)
    • github.com/eko/gocache/store/hazelcast/v4 (hazelcast)
    • github.com/eko/gocache/store/memcache/v4 (memcache)
    • github.com/eko/gocache/store/pegasus/v4 (pegasus)
    • github.com/eko/gocache/store/redis/v4 (redis)
    • github.com/eko/gocache/store/rediscluster/v4 (rediscluster)
    • github.com/eko/gocache/store/rueidis/v4 (rueidis)
    • github.com/eko/gocache/store/ristretto/v4 (ristretto)
  10. Invalidate cache by tags in Pegasus

    master
    Pegasus supports tag-based invalidation. When setting a key with tags, the store maintains an internal mapping using the gocache_tag_%s pattern. To invalidate all keys associated with a specific tag, use the Invalidate method with lib_store.WithTags.