☔️ A complete Go cache library that brings you multiple ways of managing your caches

Overview

TravisBuildStatus GoDoc GoReportCard codecov

Gocache

Guess what is Gocache? a Go cache library. This is an extendable cache library that brings you a lot of features for caching data.

Overview

Here is what it brings in detail:

  • Multiple cache stores: actually in memory, redis, or your own custom store
  • A chain cache: use multiple cache with a priority order (memory then fallback to a redis shared cache for instance)
  • A loadable cache: allow you to call a callback function to put your data back in cache
  • A metric cache to let you store metrics about your caches usage (hits, miss, set success, set error, ...)
  • A marshaler to automatically marshal/unmarshal your cache values as a struct
  • Define default values in stores and override them when setting data
  • Cache invalidation by expiration time and/or using tags

Built-in stores

Built-in metrics providers

Available cache features in detail

A simple cache

Here is a simple cache instanciation with Redis but you can also look at other available stores:

Memcache

memcacheStore := store.NewMemcache(
	memcache.New("10.0.0.1:11211", "10.0.0.2:11211", "10.0.0.3:11212"),
	&store.Options{
		Expiration: 10*time.Second,
	},
)

cacheManager := cache.New(memcacheStore)
err := cacheManager.Set("my-key", []byte("my-value"), &store.Options{
	Expiration: 15*time.Second, // Override default value of 10 seconds defined in the store
})
if err != nil {
    panic(err)
}

value := cacheManager.Get("my-key")

cacheManager.Delete("my-key")

cacheManager.Clear() // Clears the entire cache, in case you want to flush all cache

Memory (using Bigcache)

bigcacheClient, _ := bigcache.NewBigCache(bigcache.DefaultConfig(5 * time.Minute))
bigcacheStore := store.NewBigcache(bigcacheClient, nil) // No otions provided (as second argument)

cacheManager := cache.New(bigcacheStore)
err := cacheManager.Set("my-key", []byte("my-value"), nil)
if err != nil {
    panic(err)
}

value := cacheManager.Get("my-key")

Memory (using Ristretto)

ristrettoCache, err := ristretto.NewCache(&ristretto.Config{
	NumCounters: 1000,
	MaxCost: 100,
	BufferItems: 64,
})
if err != nil {
    panic(err)
}
ristrettoStore := store.NewRistretto(ristrettoCache, nil)

cacheManager := cache.New(ristrettoStore)
err := cacheManager.Set("my-key", "my-value", &store.Options{Cost: 2})
if err != nil {
    panic(err)
}

value := cacheManager.Get("my-key")

cacheManager.Delete("my-key")

Redis

redisStore := store.NewRedis(redis.NewClient(&redis.Options{
	Addr: "127.0.0.1:6379",
}), nil)

cacheManager := cache.New(redisStore)
err := cacheManager.Set("my-key", "my-value", &store.Options{Expiration: 15*time.Second})
if err != nil {
    panic(err)
}

value := cacheManager.Get("my-key")

Freecache

freecacheStore := store.NewFreecache(freecache.NewCache(1000), &Options{
	Expiration: 10 * time.Second,
})

cacheManager := cache.New(freecacheStore)
err := cacheManager.Set("by-key", []byte("my-value"), opts)
if err != nil {
	panic(err)
}

value := cacheManager.Get("my-key")

A chained cache

Here, we will chain caches in the following order: first in memory with Ristretto store, then in Redis (as a fallback):

// Initialize Ristretto cache and Redis client
ristrettoCache, err := ristretto.NewCache(&ristretto.Config{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 := store.NewRistretto(ristrettoCache, nil)
redisStore := store.NewRedis(redisClient, &store.Options{Expiration: 5*time.Second})

// Initialize chained cache
cacheManager := cache.NewChain(
    cache.New(ristrettoStore),
    cache.New(redisStore),
)

// ... Then, do what you want with your cache

Chain cache also put data back in previous caches when it's found so in this case, if ristretto doesn't have the data in its cache but redis have, data will also get setted back into ristretto (memory) cache.

A loadable cache

This cache will provide a load function that acts as a callable function and will set your data back in your cache in case they are not available:

// Initialize Redis client and store
redisClient := redis.NewClient(&redis.Options{Addr: "127.0.0.1:6379"})
redisStore := store.NewRedis(redisClient, nil)

// Initialize a load function that loads your data from a custom source
loadFunction := func(key interface{}) (interface{}, error) {
    // ... retrieve value from available source
    return &Book{ID: 1, Name: "My test amazing book", Slug: "my-test-amazing-book"}, nil
}

// Initialize loadable cache
cacheManager := cache.NewLoadable(
	loadFunction,
	cache.New(redisStore),
)

// ... Then, you can get your data and your function will automatically put them in cache(s)

Of course, you can also pass a Chain cache into the Loadable one so if your data is not available in all caches, it will bring it back in all caches.

A metric cache to retrieve cache statistics

This cache will record metrics depending on the metric provider you pass to it. Here we give a Prometheus provider:

// Initialize Redis client and store
redisClient := redis.NewClient(&redis.Options{Addr: "127.0.0.1:6379"})
redisStore := store.NewRedis(redisClient, nil)

// Initializes Prometheus metrics service
promMetrics := metrics.NewPrometheus("my-test-app")

// Initialize metric cache
cacheManager := cache.NewMetric(
	promMetrics,
	cache.New(redisStore),
)

// ... Then, you can get your data and metrics will be observed by Prometheus

A marshaler wrapper

Some caches like Redis stores and returns the value as a string so you have to marshal/unmarshal your structs if you want to cache an object. That's why we bring a marshaler service that wraps your cache and make the work for you:

// Initialize Redis client and store
redisClient := redis.NewClient(&redis.Options{Addr: "127.0.0.1:6379"})
redisStore := store.NewRedis(redisClient, nil)

// Initialize chained cache
cacheManager := cache.NewMetric(
	promMetrics,
	cache.New(redisStore),
)

// 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"}

err = marshal.Set(key, value)
if err != nil {
    panic(err)
}

returnedValue, err := marshal.Get(key, new(Book))
if err != nil {
    panic(err)
}

// Then, do what you want with the  value

marshal.Delete("my-key")

The only thing you have to do is to specify the struct in which you want your value to be un-marshalled as a second argument when calling the .Get() method.

Cache invalidation using tags

You can attach some tags to items you create so you can easily invalidate some of them later.

Tags are stored using the same storage you choose for your cache.

Here is an example on how to use it:

// Initialize Redis client and store
redisClient := redis.NewClient(&redis.Options{Addr: "127.0.0.1:6379"})
redisStore := store.NewRedis(redisClient, nil)

// Initialize chained cache
cacheManager := cache.NewMetric(
	promMetrics,
	cache.New(redisStore),
)

// 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 an item in the cache and attach it a "book" tag
err = marshal.Set(key, value, store.Options{Tags: []string{"book"}})
if err != nil {
    panic(err)
}

// Remove all items that have the "book" tag
err := marshal.Invalidate(store.InvalidateOptions{Tags: []string{"book"}})
if err != nil {
    panic(err)
}

returnedValue, err := marshal.Get(key, new(Book))
if err != nil {
	// Should be triggered because item has been deleted so it cannot be found.
    panic(err)
}

Mix this with expiration times on your caches to have a fine tuned control on how your data are cached.

Write your own custom cache

Cache respect the following interface so you can write your own (proprietary?) cache logic if needed by implementing the following interface:

type CacheInterface interface {
	Get(key interface{}) (interface{}, error)
	Set(key, object interface{}, options *store.Options) error
	Delete(key interface{}) error
	Invalidate(options store.InvalidateOptions) error
	Clear() error
	GetType() string
}

Or, in case you use a setter cache, also implement the GetCodec() method:

type SetterCacheInterface interface {
	CacheInterface

	GetCodec() codec.CodecInterface
}

As all caches available in this library implement CacheInterface, you will be able to mix your own caches with your own.

Write your own custom store

You also have the ability to write your own custom store by implementing the following interface:

type StoreInterface interface {
	Get(key interface{}) (interface{}, error)
	Set(key interface{}, value interface{}, options *Options) error
	Delete(key interface{}) error
	Invalidate(options InvalidateOptions) error
	Clear() error
	GetType() string
}

Of course, I suggest you to have a look at current caches or stores to implement your own.

Benchmarks

Benchmarks

Community

Please feel free to contribute on this library and do not hesitate to open an issue if you want to discuss about a feature.

Run tests

Generate mocks:

$ go get github.com/golang/mock/mockgen
$ make mocks

Test suite can be run with:

$ go test -v ./...
Issues
  • Wrong type for method Del when initialize Redis Store

    Wrong type for method Del when initialize Redis Store

    I want to implement a chained cache with Redis and BigCache. I don't have problem to declare Bigcache store, but have problem with redis. I using redis from "github.com/go-redis/redis", gocache store and gocache cache

    this is how i declare my cache:

    var LocationCache *cache.ChainCache
    
    func createCache(host string) *cache.ChainCache {
    	redisClient := redis.NewClient(&redis.Options{Addr: host})
    	bigcacheClient, _ := bigcache.NewBigCache(bigcache.DefaultConfig(720 * time.Hour))
    	bigcacheStorage := store.NewBigcache(bigcacheClient, nil)
    	redisStorage := store.NewRedis(redisClient, nil)
    
    	LocationCache = cache.NewChain(
    		cache.New(bigcacheStorage),
    		cache.New(redisStorage))
    	return LocationCache
    }
    

    But it give me this error: cannot use redisClient (variable of type *redis.Client) as store.RedisClientInterface value in argument to store.NewRedis: wrong type for method Del"

    Is anyone can help me? Thanks

    opened by Yosafat1997 5
  • go mod unable to get latest version v2.2.0

    go mod unable to get latest version v2.2.0

    go mod tidy

    go: finding module for package github.com/eko/gocache github.com/eko/gocache: module github.com/eko/[email protected] found (v1.2.0), but does not contain package github.com/eko/gocache

    import (
    	"github.com/eko/gocache"
    )
    
    func main() {
       //some code
    }
    
    opened by herozzm 4
  • Use hset for invalidate tag list instead of a string

    Use hset for invalidate tag list instead of a string

    The redis store uses a csv string in redis to keep the cache keys for each tag. This redis entry that keep all keys in csv format can grow fast if we group a lot of entries under the same tag. When accessing it, this big string is loaded in memory. This result to a big memory allocation/de-allocation every time an entry with a tag is written into the cache. To fix this issue, we need to change the format of the tag key. It would be better to use a hset. This way, we can read/write only the entry we need.

    opened by plbouchard 4
  • Implement GetWithTTL for Freecache

    Implement GetWithTTL for Freecache

    Freecache doesn't implement interface function GetWithTTL. I assume that the person that added Freecache integration didn't pull the latest changes from master.

    opened by corinapurcarea 4
  • Fix data races by removing unguarded goroutines; run mod tidy

    Fix data races by removing unguarded goroutines; run mod tidy

    Fixes #15

    • Remove goroutines that are causing data races
    • Also ran go mod tidy to remove unneeded modules

    Before

    $ go test -v -race ./...
    
    ...
    ==================
    WARNING: DATA RACE
    Read at 0x00c00014a9c8 by goroutine 58:
      reflect.typedmemmove()
          /usr/local/Cellar/go/1.13.4/libexec/src/runtime/mbarrier.go:177 +0x0
      reflect.packEface()
          /usr/local/Cellar/go/1.13.4/libexec/src/reflect/value.go:119 +0x103
      reflect.valueInterface()
          /usr/local/Cellar/go/1.13.4/libexec/src/reflect/value.go:1033 +0x16f
      fmt.(*pp).printValue()
          /usr/local/Cellar/go/1.13.4/libexec/src/reflect/value.go:1003 +0x38f7
      fmt.(*pp).printValue()
          /usr/local/Cellar/go/1.13.4/libexec/src/fmt/print.go:880 +0x25da
      fmt.(*pp).printArg()
          /usr/local/Cellar/go/1.13.4/libexec/src/fmt/print.go:716 +0x2ee
      fmt.(*pp).doPrintf()
          /usr/local/Cellar/go/1.13.4/libexec/src/fmt/print.go:1126 +0x912
      fmt.Sprintf()
          /usr/local/Cellar/go/1.13.4/libexec/src/fmt/print.go:219 +0x73
      github.com/stretchr/testify/mock.Arguments.Diff()
          /Users/markphelps/go/pkg/mod/github.com/stretchr/[email protected]/mock/mock.go:687 +0xf1a
      github.com/stretchr/testify/mock.(*Mock).findExpectedCall()
          /Users/markphelps/go/pkg/mod/github.com/stretchr/[email protected]/mock/mock.go:269 +0x16a
      github.com/stretchr/testify/mock.(*Mock).MethodCalled()
          /Users/markphelps/go/pkg/mod/github.com/stretchr/[email protected]/mock/mock.go:348 +0xb3
      github.com/stretchr/testify/mock.(*Mock).Called()
          /Users/markphelps/go/pkg/mod/github.com/stretchr/[email protected]/mock/mock.go:338 +0x1e4
      github.com/eko/gocache/test/mocks/metrics.(*MetricsInterface).RecordFromCodec()
          /Users/markphelps/workspace/gocache/test/mocks/metrics/metrics_interface.go:21 +0xaa
    
    Previous write at 0x00c00014a9c8 by goroutine 57:
      github.com/stretchr/testify/mock.(*Mock).MethodCalled()
          /Users/markphelps/go/pkg/mod/github.com/stretchr/[email protected]/mock/mock.go:385 +0x7b6
      github.com/stretchr/testify/mock.(*Mock).Called()
          /Users/markphelps/go/pkg/mod/github.com/stretchr/[email protected]/mock/mock.go:338 +0x1e4
      github.com/eko/gocache/test/mocks/codec.(*CodecInterface).GetStore()
          /Users/markphelps/workspace/gocache/test/mocks/codec/codec_interface.go:83 +0x63
      github.com/eko/gocache/cache.(*ChainCache).setUntil()
          /Users/markphelps/workspace/gocache/cache/chain.go:90 +0x13b
    
    Goroutine 58 (running) created at:
      github.com/eko/gocache/cache.(*MetricCache).updateMetrics()
          /Users/markphelps/workspace/gocache/cache/metric.go:65 +0x1bd
      github.com/eko/gocache/cache.(*MetricCache).updateMetrics()
          /Users/markphelps/workspace/gocache/cache/metric.go:61 +0xff
      github.com/eko/gocache/cache.(*MetricCache).Get()
          /Users/markphelps/workspace/gocache/cache/metric.go:31 +0xcb
      github.com/eko/gocache/cache.TestMetricGetWhenChainCache()
          /Users/markphelps/workspace/gocache/cache/metric_test.go:83 +0x714
      testing.tRunner()
          /usr/local/Cellar/go/1.13.4/libexec/src/testing/testing.go:909 +0x199
    
    Goroutine 57 (finished) created at:
      github.com/eko/gocache/cache.(*ChainCache).Get()
          /Users/markphelps/workspace/gocache/cache/chain.go:37 +0x383
      github.com/eko/gocache/cache.(*MetricCache).Get()
          /Users/markphelps/workspace/gocache/cache/metric.go:29 +0x75
      github.com/eko/gocache/cache.TestMetricGetWhenChainCache()
          /Users/markphelps/workspace/gocache/cache/metric_test.go:83 +0x714
      testing.tRunner()
          /usr/local/Cellar/go/1.13.4/libexec/src/testing/testing.go:909 +0x199
    ==================
    ==================
    WARNING: DATA RACE
    Read at 0x00c00014a9f8 by goroutine 58:
      reflect.typedmemmove()
          /usr/local/Cellar/go/1.13.4/libexec/src/runtime/mbarrier.go:177 +0x0
    --- FAIL: TestMetricSet (0.00s)
      reflect.packEface()
          /usr/local/Cellar/go/1.13.4/libexec/src/reflect/value.go:119 +0x103
        testing.go:853: race detected during execution of test
      reflect.valueInterface()
          /usr/local/Cellar/go/1.13.4/libexec/src/reflect/value.go:1033 +0x16f
      fmt.(*pp).printValue()
          /usr/local/Cellar/go/1.13.4/libexec/src/reflect/value.go:1003 +0x38f7
      fmt.(*pp).printValue()
          /usr/local/Cellar/go/1.13.4/libexec/src/fmt/print.go:880 +0x25da
      fmt.(*pp).printArg()
          /usr/local/Cellar/go/1.13.4/libexec/src/fmt/print.go:716 +0x2ee
      fmt.(*pp).doPrintf()
          /usr/local/Cellar/go/1.13.4/libexec/src/fmt/print.go:1126 +0x912
      fmt.Sprintf()
          /usr/local/Cellar/go/1.13.4/libexec/src/fmt/print.go:219 +0x73
      github.com/stretchr/testify/mock.Arguments.Diff()
          /Users/markphelps/go/pkg/mod/github.com/stretchr/[email protected]/mock/mock.go:687 +0xf1a
      github.com/stretchr/testify/mock.(*Mock).findExpectedCall()
          /Users/markphelps/go/pkg/mod/github.com/stretchr/[email protected]/mock/mock.go:269 +0x16a
      github.com/stretchr/testify/mock.(*Mock).MethodCalled()
          /Users/markphelps/go/pkg/mod/github.com/stretchr/[email protected]/mock/mock.go:348 +0xb3
      github.com/stretchr/testify/mock.(*Mock).Called()
          /Users/markphelps/go/pkg/mod/github.com/stretchr/[email protected]/mock/mock.go:338 +0x1e4
      github.com/eko/gocache/test/mocks/metrics.(*MetricsInterface).RecordFromCodec()
          /Users/markphelps/workspace/gocache/test/mocks/metrics/metrics_interface.go:21 +0xaa
    
    Previous write at 0x00c00014a9f8 by goroutine 57:
      sync/atomic.AddInt32()
          /usr/local/Cellar/go/1.13.4/libexec/src/runtime/race_amd64.s:269 +0xb
      sync.(*Mutex).Unlock()
          /usr/local/Cellar/go/1.13.4/libexec/src/sync/mutex.go:186 +0x51
      github.com/stretchr/testify/mock.(*Mock).MethodCalled()
          /Users/markphelps/go/pkg/mod/github.com/stretchr/[email protected]/mock/mock.go:405 +0x921
      github.com/stretchr/testify/mock.(*Mock).Called()
          /Users/markphelps/go/pkg/mod/github.com/stretchr/[email protected]/mock/mock.go:338 +0x1e4
      github.com/eko/gocache/test/mocks/codec.(*CodecInterface).GetStore()
          /Users/markphelps/workspace/gocache/test/mocks/codec/codec_interface.go:83 +0x63
      github.com/eko/gocache/cache.(*ChainCache).setUntil()
          /Users/markphelps/workspace/gocache/cache/chain.go:90 +0x13b
    
    Goroutine 58 (running) created at:
      github.com/eko/gocache/cache.(*MetricCache).updateMetrics()
          /Users/markphelps/workspace/gocache/cache/metric.go:65 +0x1bd
      github.com/eko/gocache/cache.(*MetricCache).updateMetrics()
          /Users/markphelps/workspace/gocache/cache/metric.go:61 +0xff
      github.com/eko/gocache/cache.(*MetricCache).Get()
          /Users/markphelps/workspace/gocache/cache/metric.go:31 +0xcb
      github.com/eko/gocache/cache.TestMetricGetWhenChainCache()
          /Users/markphelps/workspace/gocache/cache/metric_test.go:83 +0x714
      testing.tRunner()
          /usr/local/Cellar/go/1.13.4/libexec/src/testing/testing.go:909 +0x199
    === RUN   TestMetricDelete
    
    Goroutine 57 (finished) created at:
      github.com/eko/gocache/cache.(*ChainCache).Get()
          /Users/markphelps/workspace/gocache/cache/chain.go:37 +0x383
      github.com/eko/gocache/cache.(*MetricCache).Get()
          /Users/markphelps/workspace/gocache/cache/metric.go:29 +0x75
      github.com/eko/gocache/cache.TestMetricGetWhenChainCache()
          /Users/markphelps/workspace/gocache/cache/metric_test.go:83 +0x714
      testing.tRunner()
          /usr/local/Cellar/go/1.13.4/libexec/src/testing/testing.go:909 +0x199
    ==================
    ==================
    WARNING: DATA RACE
    Read at 0x00c0001f6870 by goroutine 58:
      reflect.typedmemmove()
          /usr/local/Cellar/go/1.13.4/libexec/src/runtime/mbarrier.go:177 +0x0
      reflect.packEface()
          /usr/local/Cellar/go/1.13.4/libexec/src/reflect/value.go:119 +0x103
      reflect.valueInterface()
          /usr/local/Cellar/go/1.13.4/libexec/src/reflect/value.go:1033 +0x16f
      fmt.(*pp).printValue()
          /usr/local/Cellar/go/1.13.4/libexec/src/reflect/value.go:1003 +0x38f7
      fmt.(*pp).printValue()
          /usr/local/Cellar/go/1.13.4/libexec/src/fmt/print.go:869 +0xec7
      fmt.(*pp).printValue()
          /usr/local/Cellar/go/1.13.4/libexec/src/fmt/print.go:810 +0x283f
      fmt.(*pp).printValue()
          /usr/local/Cellar/go/1.13.4/libexec/src/fmt/print.go:810 +0x283f
      fmt.(*pp).printValue()
          /usr/local/Cellar/go/1.13.4/libexec/src/fmt/print.go:880 +0x25da
      fmt.(*pp).printArg()
          /usr/local/Cellar/go/1.13.4/libexec/src/fmt/print.go:716 +0x2ee
      fmt.(*pp).doPrintf()
          /usr/local/Cellar/go/1.13.4/libexec/src/fmt/print.go:1126 +0x912
      fmt.Sprintf()
          /usr/local/Cellar/go/1.13.4/libexec/src/fmt/print.go:219 +0x73
      github.com/stretchr/testify/mock.Arguments.Diff()
          /Users/markphelps/go/pkg/mod/github.com/stretchr/[email protected]/mock/mock.go:687 +0xf1a
      github.com/stretchr/testify/mock.(*Mock).findExpectedCall()
          /Users/markphelps/go/pkg/mod/github.com/stretchr/[email protected]/mock/mock.go:269 +0x16a
      github.com/stretchr/testify/mock.(*Mock).MethodCalled()
          /Users/markphelps/go/pkg/mod/github.com/stretchr/[email protected]/mock/mock.go:348 +0xb3
      github.com/stretchr/testify/mock.(*Mock).Called()
          /Users/markphelps/go/pkg/mod/github.com/stretchr/[email protected]/mock/mock.go:338 +0x1e4
      github.com/eko/gocache/test/mocks/metrics.(*MetricsInterface).RecordFromCodec()
          /Users/markphelps/workspace/gocache/test/mocks/metrics/metrics_interface.go:21 +0xaa
    
    Previous write at 0x00c0001f6870 by goroutine 57:
      github.com/stretchr/testify/mock.(*Mock).MethodCalled()
          /Users/markphelps/go/pkg/mod/github.com/stretchr/[email protected]/mock/mock.go:385 +0x775
      github.com/stretchr/testify/mock.(*Mock).Called()
          /Users/markphelps/go/pkg/mod/github.com/stretchr/[email protected]/mock/mock.go:338 +0x1e4
      github.com/eko/gocache/test/mocks/codec.(*CodecInterface).GetStore()
          /Users/markphelps/workspace/gocache/test/mocks/codec/codec_interface.go:83 +0x63
      github.com/eko/gocache/cache.(*ChainCache).setUntil()
          /Users/markphelps/workspace/gocache/cache/chain.go:90 +0x13b
    
    Goroutine 58 (running) created at:
      github.com/eko/gocache/cache.(*MetricCache).updateMetrics()
          /Users/markphelps/workspace/gocache/cache/metric.go:65 +0x1bd
      github.com/eko/gocache/cache.(*MetricCache).updateMetrics()
          /Users/markphelps/workspace/gocache/cache/metric.go:61 +0xff
      github.com/eko/gocache/cache.(*MetricCache).Get()
          /Users/markphelps/workspace/gocache/cache/metric.go:31 +0xcb
      github.com/eko/gocache/cache.TestMetricGetWhenChainCache()
          /Users/markphelps/workspace/gocache/cache/metric_test.go:83 +0x714
      testing.tRunner()
          /usr/local/Cellar/go/1.13.4/libexec/src/testing/testing.go:909 +0x199
    
    Goroutine 57 (finished) created at:
      github.com/eko/gocache/cache.(*ChainCache).Get()
          /Users/markphelps/workspace/gocache/cache/chain.go:37 +0x383
      github.com/eko/gocache/cache.(*MetricCache).Get()
          /Users/markphelps/workspace/gocache/cache/metric.go:29 +0x75
      github.com/eko/gocache/cache.TestMetricGetWhenChainCache()
          /Users/markphelps/workspace/gocache/cache/metric_test.go:83 +0x714
      testing.tRunner()
          /usr/local/Cellar/go/1.13.4/libexec/src/testing/testing.go:909 +0x199
    ==================
    --- FAIL: TestMetricDelete (0.00s)
        testing.go:853: race detected during execution of test
    === RUN   TestMetricDeleteWhenError
    --- PASS: TestMetricDeleteWhenError (0.00s)
    === RUN   TestMetricInvalidate
    ==================
    WARNING: DATA RACE
    Read at 0x00c0002dcba0 by goroutine 58:
      reflect.Value.String()
          /usr/local/Cellar/go/1.13.4/libexec/src/reflect/value.go:1845 +0x5d
      fmt.(*pp).printValue()
          /usr/local/Cellar/go/1.13.4/libexec/src/fmt/print.go:761 +0x3156
      fmt.(*pp).printValue()
          /usr/local/Cellar/go/1.13.4/libexec/src/fmt/print.go:869 +0xec7
      fmt.(*pp).printValue()
          /usr/local/Cellar/go/1.13.4/libexec/src/fmt/print.go:810 +0x283f
      fmt.(*pp).printValue()
          /usr/local/Cellar/go/1.13.4/libexec/src/fmt/print.go:869 +0xec7
      fmt.(*pp).printValue()
          /usr/local/Cellar/go/1.13.4/libexec/src/fmt/print.go:810 +0x283f
      fmt.(*pp).printValue()
          /usr/local/Cellar/go/1.13.4/libexec/src/fmt/print.go:810 +0x283f
      fmt.(*pp).printValue()
          /usr/local/Cellar/go/1.13.4/libexec/src/fmt/print.go:880 +0x25da
      fmt.(*pp).printArg()
          /usr/local/Cellar/go/1.13.4/libexec/src/fmt/print.go:716 +0x2ee
      fmt.(*pp).doPrintf()
          /usr/local/Cellar/go/1.13.4/libexec/src/fmt/print.go:1126 +0x912
      fmt.Sprintf()
          /usr/local/Cellar/go/1.13.4/libexec/src/fmt/print.go:219 +0x73
      github.com/stretchr/testify/mock.Arguments.Diff()
          /Users/markphelps/go/pkg/mod/github.com/stretchr/[email protected]/mock/mock.go:687 +0xf1a
      github.com/stretchr/testify/mock.(*Mock).findExpectedCall()
          /Users/markphelps/go/pkg/mod/github.com/stretchr/[email protected]/mock/mock.go:269 +0x16a
      github.com/stretchr/testify/mock.(*Mock).MethodCalled()
          /Users/markphelps/go/pkg/mod/github.com/stretchr/[email protected]/mock/mock.go:348 +0xb3
      github.com/stretchr/testify/mock.(*Mock).Called()
          /Users/markphelps/go/pkg/mod/github.com/stretchr/[email protected]/mock/mock.go:338 +0x1e4
      github.com/eko/gocache/test/mocks/metrics.(*MetricsInterface).RecordFromCodec()
          /Users/markphelps/workspace/gocache/test/mocks/metrics/metrics_interface.go:21 +0xaa
    
    Previous write at 0x00c0002dcba0 by goroutine 57:
      github.com/stretchr/testify/assert.CallerInfo()
          /Users/markphelps/go/pkg/mod/github.com/stretchr/[email protected]/assert/assertions.go:146 +0x3c3
      github.com/stretchr/testify/mock.(*Mock).MethodCalled()
          /Users/markphelps/go/pkg/mod/github.com/stretchr/[email protected]/mock/mock.go:385 +0x57e
      github.com/stretchr/testify/mock.(*Mock).Called()
          /Users/markphelps/go/pkg/mod/github.com/stretchr/[email protected]/mock/mock.go:338 +0x1e4
      github.com/eko/gocache/test/mocks/codec.(*CodecInterface).GetStore()
          /Users/markphelps/workspace/gocache/test/mocks/codec/codec_interface.go:83 +0x63
      github.com/eko/gocache/cache.(*ChainCache).setUntil()
          /Users/markphelps/workspace/gocache/cache/chain.go:90 +0x13b
    
    Goroutine 58 (running) created at:
      github.com/eko/gocache/cache.(*MetricCache).updateMetrics()
          /Users/markphelps/workspace/gocache/cache/metric.go:65 +0x1bd
      github.com/eko/gocache/cache.(*MetricCache).updateMetrics()
          /Users/markphelps/workspace/gocache/cache/metric.go:61 +0xff
      github.com/eko/gocache/cache.(*MetricCache).Get()
          /Users/markphelps/workspace/gocache/cache/metric.go:31 +0xcb
      github.com/eko/gocache/cache.TestMetricGetWhenChainCache()
          /Users/markphelps/workspace/gocache/cache/metric_test.go:83 +0x714
      testing.tRunner()
          /usr/local/Cellar/go/1.13.4/libexec/src/testing/testing.go:909 +0x199
    
    Goroutine 57 (finished) created at:
      github.com/eko/gocache/cache.(*ChainCache).Get()
          /Users/markphelps/workspace/gocache/cache/chain.go:37 +0x383
      github.com/eko/gocache/cache.(*MetricCache).Get()
          /Users/markphelps/workspace/gocache/cache/metric.go:29 +0x75
      github.com/eko/gocache/cache.TestMetricGetWhenChainCache()
          /Users/markphelps/workspace/gocache/cache/metric_test.go:83 +0x714
      testing.tRunner()
          /usr/local/Cellar/go/1.13.4/libexec/src/testing/testing.go:909 +0x199
    ==================
    --- FAIL: TestMetricInvalidate (0.00s)
        testing.go:853: race detected during execution of test
    ...
    FAIL
    

    After

    $ go test -v -race ./...
    
    ...
    === RUN   TestRistrettoGetType
    --- PASS: TestRistrettoGetType (0.00s)
    PASS
    ok      github.com/eko/gocache/store    (cached)
    ?       github.com/eko/gocache/test/mocks/cache [no test files]
    ?       github.com/eko/gocache/test/mocks/codec [no test files]
    ?       github.com/eko/gocache/test/mocks/metrics       [no test files]
    ?       github.com/eko/gocache/test/mocks/store [no test files]
    ?       github.com/eko/gocache/test/mocks/store/clients [no test files]
    
    opened by markphelps 4
  • Redis V8

    Redis V8

    Hi there! I'm about to upgrade redis lib to V8. I wanted to know, before I start, if there is any particular reason of using v7 instead of v8? and why the upgrade isn't done today?

    Any considerations I should know?

    Thanks in advance.

    Jose.-

    opened by josefld 3
  • remove-log: drop logging in two places

    remove-log: drop logging in two places

    • it didn't appear that logging is absolutely necessary because errors are returned
    • this can be cumbersome if you use a structured logger
    • libraries probably shouldn't write to stdout/stderr
    opened by elisarver 3
  • Do not hash key if its type is string

    Do not hash key if its type is string

    For keys that already have string type, hashing could be skipped. Reasons to do so:

    • integration tests will be easier to do mainly because the method that does the hashing is not public;
    • some cache mechanism like Redis Pub/Sub need a pattern to listen for events;
    opened by corinapurcarea 3
  • There is a bug in the Invalidate method in the redis store

    There is a bug in the Invalidate method in the redis store

    I'm not sure of the correct fix. But here is the problem

    In the setTags function of RedisStore

    You set the tag for the key like so

    s.Set(tagKey, []byte(strings.Join(cacheKeys, ",")), &Options{
    			Expiration: 720 * time.Hour,
    })
    

    Then in Invalidate function of RedisStore

    You guys do the following

    	result, err := s.Get(tagKey)
    			if err != nil {
    				fmt.Println("Didn't find tag!!")
    				return nil
    			}
    
    			var cacheKeys = []string{}
    			if bytes, ok := result.([]byte); ok {
    				cacheKeys = strings.Split(string(bytes), ",")
    			}
    
    

    You type assert the result to a []byte.

    But this assert fails because result is actually of type string

    As you can see if you look at the implementation of RedisStore Get

    func (s *RedisStore) Get(key interface{}) (interface{}, error) { return s.client.Get(key.(string)).Result() }

    But the Result function returns a (string,error)

    I think what you want is this

    func (s *RedisStore) Get(key interface{}) (interface{}, error) { return s.client.Get(key.(string)).Bytes() }

    At least this is the change I made to my local copy to get Invalidate to work.

    opened by neitzj 3
  • It's impossible to create my own cache

    It's impossible to create my own cache

    The options struct is not public, so it's not really viable to implement my own cache since I can't use the v3 Option type. Option is just a func that takes private struct as input so I can't use it in my own package. I think the options struct should be public.

    opened by wexder 2
  • update redis

    update redis

    So v9 isn't quite ready. Is there another way to make this compatible without changing the dependency? I'd be willing to submit a PR but I don't know what the solution here is.

    Could potentially make a simpler interface and then add v8/v9 adapters. Any thoughts ?

    opened by Ashtonian 2
  • Get method doesn't work correctly for bigcache with string type.

    Get method doesn't work correctly for bigcache with string type.

    Description Hi,

    Thank you for making the awesome library first.

    The type casting code is wrong for bigcache with string type. Because bigcache always returns []byte type(refer here) even though we can store data as string type.

    I think it is better if type casting is failed, it should return not only zero value but also error.

    Steps for Reproduction

    1. Set up Bigcache with string type
    func fn(config Config) {
      bigcacheClient, _ := bigcache.NewBigCache(bigcache.DefaultConfig(config.ExpiredTime))
      bigcacheStore := store.NewBigcache(bigcacheClient)
    
      memoryCache = cache.New[string](bigcacheStore)
    }
    
    1. Set data
    val := "some string data"
    memoryCache.Set(ctx, key, val) // There is no error because it will be convert to byte array
    
    1. Get data
    val, _ := memoryCache.Get(ctx, key) // There is no error but data is blank string.
    

    Expected behavior: It should be return stored string data.

    Actual behavior: It returned blank string.

    Platforms: Ubuntu

    Versions: v3.1.1

    opened by ByungJun25 0
  • [Error While Compiling] Missing go.sum for X, Y, Z after installing the library

    [Error While Compiling] Missing go.sum for X, Y, Z after installing the library

    I installed the library as documented

    go get github.com/eko/gocache/v3

    then I installed the in-memory store

    go get github.com/patrickmn/go-cache

    And I have a code without any syntax error like this

    package main
    
    import (
    	"context"
    	"fmt"
    	"github.com/eko/gocache/v3/cache"
    	"github.com/eko/gocache/v3/store"
    	gocache "github.com/patrickmn/go-cache"
    	"time"
    )
    
    func main() {
    	cacheManager, _ := createCache()
    	err := cacheManager.Set(context.Background(), "my-key", []byte("my-value"))
    	if err != nil {
    		panic(err)
    	}
    
    	value, err := cacheManager.Get(context.Background(), "my-key")
    	if err != nil {
    		panic(err)
    	}
    	fmt.Printf("%s", value)
    
    }
    
    func createCache() (*cache.Cache[[]byte], error) {
    	gocacheClient := gocache.New(5*time.Minute, 10*time.Minute)
    	gocacheStore := store.NewGoCache(gocacheClient)
    	cacheManager := cache.New[[]byte](gocacheStore)
    
    	return cacheManager, nil
    }
    

    When trying to compile I get error as below (yes I tried also go mod tidy and did not help)

    ../../../go/pkg/mod/github.com/eko/gocache/[email protected]/store/pegasus.go:10:2: missing go.sum entry for module providing package github.com/XiaoMi/pegasus-go-client/admin (imported by github.com/eko/gocache/v3/store); to add:
            go get github.com/eko/gocache/v3/[email protected]
    ../../../go/pkg/mod/github.com/eko/gocache/[email protected]/store/pegasus.go:11:2: missing go.sum entry for module providing package github.com/XiaoMi/pegasus-go-client/pegasus (imported by github.com/eko/gocache/v3/store); to add:
            go get github.com/eko/gocache/v3/[email protected]
    ../../../go/pkg/mod/github.com/eko/gocache/[email protected]/store/memcache.go:12:2: missing go.sum entry for module providing package github.com/bradfitz/gomemcache/memcache (imported by github.com/eko/gocache/v3/store); to add:
            go get github.com/eko/gocache/v3/[email protected]
    ../../../go/pkg/mod/github.com/eko/gocache/[email protected]/store/redis.go:8:2: missing go.sum entry for module providing package github.com/go-redis/redis/v8 (imported by github.com/eko/gocache/v3/store); to add:
            go get github.com/eko/gocache/v3/[email protected]
    ../../../go/pkg/mod/github.com/gin-gonic/[email protected]/binding/protobuf.go:11:2: missing go.sum entry for module providing package github.com/golang/protobuf/proto (imported by github.com/gin-gonic/gin/binding); to add:
            go get github.com/gin-gonic/gin/[email protected]
    ../../../go/pkg/mod/github.com/eko/gocache/[email protected]/metrics/prometheus.go:5:2: missing go.sum entry for module providing package github.com/prometheus/client_golang/prometheus (imported by github.com/eko/gocache/v3/metrics); to add:
            go get github.com/eko/gocache/v3/[email protected]
    ../../../go/pkg/mod/github.com/eko/gocache/[email protected]/metrics/prometheus.go:6:2: missing go.sum entry for module providing package github.com/prometheus/client_golang/prometheus/promauto (imported by github.com/eko/gocache/v3/metrics); to add:
            go get github.com/eko/gocache/v3/[email protected]
    ../../../go/pkg/mod/github.com/eko/gocache/[email protected]/store/pegasus.go:12:2: missing go.sum entry for module providing package github.com/spf13/cast (imported by github.com/eko/gocache/v3/store); to add:
            go get github.com/eko/gocache/v3/[email protected]
    ../../../go/pkg/mod/github.com/eko/gocache/[email protected]/store/options_test_matchers.go:7:2: missing go.sum entry for module providing package golang.org/x/exp/slices (imported by github.com/eko/gocache/v3/store); to add:
            go get github.com/eko/gocache/v3/[email protected]
    ../../../go/pkg/mod/github.com/eko/gocache/[email protected]/store/memcache.go:10:2: missing go.sum entry for module providing package golang.org/x/sync/errgroup (imported by github.com/eko/gocache/v3/store); to add:
            go get github.com/eko/gocache/v3/[email protected]
    make: *** [build] Error 1
    
    
    opened by kristijorgji 0
  • How to create a key that never expires

    How to create a key that never expires

    Please describe the a concise description and fill out the details below. It will help others efficiently understand your request and get to an answer instead of repeated back and forth. Providing a minimal, complete and verifiable example will further increase your chances that someone can help.

    Steps for Reproduction

    1. Set up the following "xxxx" value in the config.yaml configuration file
    2. Launch binary with the following arguments
    3. Step Two
    4. Step Three

    Expected behavior: Create a key that does not expire Actual behavior: The TTL type only supports time.Duration and cannot pass in negative values Platforms:

    Include browser, operating system and respective versions

    Versions: 3.1.1 Which versions are you running?

    opened by OneSeven 0
  • support custom prometheus registry

    support custom prometheus registry

    Steps for Reproduction

    Currently, the prometheus metrics implementation for the cache only supports the use of the default registerer. This introduces global state into peoples applications and makes it difficult for people with custom registerers to use the prometheus metrics implementation.

    Expected behavior:

    allow people the option of using a custom metrics registry

    Actual behavior:

    No metrics for people using a custom prometheus metrics registry

    Platforms:

    Include browser, operating system and respective versions

    Versions:

    Which versions are you running?

    opened by jack-evans 0
  • Error while building go application, issue with github.com/XiaoMi/pegasus-go-client

    Error while building go application, issue with github.com/XiaoMi/pegasus-go-client

    Unable to build go application on go version 1.18.2 on MacOS and Ubuntu My guess is that problem is in this library: https://github.com/XiaoMi/pegasus-go-client which is used in github.com/eko/gocache/v3/store

    image

    Steps for Reproduction

    1. Use store.WithExpiration(5*time.Minute) in code Error is there even if using any other time value

    Expected behavior: App should build

    Actual behavior: Error while building application

    Error Log:

    [email protected]: …/AlitaGoRobot [ Beta][+3595 -17369][📦🗑️×22📝×41🛤️ ×2][🐳 desktop-linux][🐹 v1.18.2][🐏 11GiB/16GiB]
    ❯ go build .
    # github.com/XiaoMi/pegasus-go-client/idl/cmd
    vendor/github.com/XiaoMi/pegasus-go-client/idl/cmd/cmd.go:41:15: not enough arguments in call to iprot.ReadStructBegin
            have ()
            want (context.Context)
    vendor/github.com/XiaoMi/pegasus-go-client/idl/cmd/cmd.go:46:35: not enough arguments in call to iprot.ReadFieldBegin
            have ()
            want (context.Context)
    vendor/github.com/XiaoMi/pegasus-go-client/idl/cmd/cmd.go:60:26: not enough arguments in call to iprot.Skip
            have (thrift.TType)
            want (context.Context, thrift.TType)
    vendor/github.com/XiaoMi/pegasus-go-client/idl/cmd/cmd.go:70:26: not enough arguments in call to iprot.Skip
            have (thrift.TType)
            want (context.Context, thrift.TType)
    vendor/github.com/XiaoMi/pegasus-go-client/idl/cmd/cmd.go:75:25: not enough arguments in call to iprot.Skip
            have (thrift.TType)
            want (context.Context, thrift.TType)
    vendor/github.com/XiaoMi/pegasus-go-client/idl/cmd/cmd.go:79:13: not enough arguments in call to iprot.ReadFieldEnd
            have ()
            want (context.Context)
    vendor/github.com/XiaoMi/pegasus-go-client/idl/cmd/cmd.go:83:12: not enough arguments in call to iprot.ReadStructEnd
            have ()
            want (context.Context)
    vendor/github.com/XiaoMi/pegasus-go-client/idl/cmd/cmd.go:90:15: not enough arguments in call to iprot.ReadString
            have ()
            want (context.Context)
    vendor/github.com/XiaoMi/pegasus-go-client/idl/cmd/cmd.go:99:18: not enough arguments in call to iprot.ReadListBegin
            have ()
            want (context.Context)
    vendor/github.com/XiaoMi/pegasus-go-client/idl/cmd/cmd.go:107:16: not enough arguments in call to iprot.ReadString
            have ()
            want (context.Context)
    vendor/github.com/XiaoMi/pegasus-go-client/idl/cmd/cmd.go:107:16: too many errors
    # github.com/XiaoMi/pegasus-go-client/idl/base
    vendor/github.com/XiaoMi/pegasus-go-client/idl/base/blob.go:18:15: not enough arguments in call to iprot.ReadBinary
            have ()
            want (context.Context)
    vendor/github.com/XiaoMi/pegasus-go-client/idl/base/blob.go:27:27: not enough arguments in call to oprot.WriteBinary
            have ([]byte)
            want (context.Context, []byte)
    vendor/github.com/XiaoMi/pegasus-go-client/idl/base/error_code.go:94:18: not enough arguments in call to iprot.ReadString
            have ()
            want (context.Context)
    vendor/github.com/XiaoMi/pegasus-go-client/idl/base/error_code.go:99:27: not enough arguments in call to oprot.WriteString
            have (string)
            want (context.Context, string)
    vendor/github.com/XiaoMi/pegasus-go-client/idl/base/gpid.go:18:12: not enough arguments in call to iprot.ReadI64
            have ()
            want (context.Context)
    vendor/github.com/XiaoMi/pegasus-go-client/idl/base/gpid.go:30:24: not enough arguments in call to oprot.WriteI64
            have (int64)
            want (context.Context, int64)
    vendor/github.com/XiaoMi/pegasus-go-client/idl/base/rpc_address.go:26:18: not enough arguments in call to iprot.ReadI64
            have ()
            want (context.Context)
    vendor/github.com/XiaoMi/pegasus-go-client/idl/base/rpc_address.go:35:24: not enough arguments in call to oprot.WriteI64
            have (int64)
            want (context.Context, int64)
    

    Platforms:

    • MacOS Monterey Version 12.3.1 (21E258)
    • Ubuntu 20.04 LTS

    Include browser, operating system and respective versions

    Versions:

    • v3.0.0 (latest)

    Which versions are you running? Go Version: v1.18.2 gocache version: v3.0.0 OS: MacOS 12.3.1 and Ubuntu 20.04 LTS

    opened by Divkix 5
  • How to use different versions of gocahce?

    How to use different versions of gocahce?

    Hello author: Thank you very much for open sourcing the gocache project, it will be very helpful to me; however I don't know much about gochache, I have encountered various problems in using gochache, I can't even run my project, can you make a tutorial on gochache, starting from the main function; my errors: v1: image v2: image

    opened by daniuEvan 0
Releases(v3.1.1)
  • v3.1.1(Jul 13, 2022)

    What's Changed

    • Update README.md - fixing go-redis link by @ralbt in https://github.com/eko/gocache/pull/154
    • Bump github.com/stretchr/testify from 1.7.2 to 1.7.4 by @dependabot in https://github.com/eko/gocache/pull/156
    • change style use tools gofumpt golangci-lint by @fmyxyz in https://github.com/eko/gocache/pull/155
    • Bump github.com/stretchr/testify from 1.7.4 to 1.7.5 by @dependabot in https://github.com/eko/gocache/pull/157
    • Bump github.com/stretchr/testify from 1.7.5 to 1.8.0 by @dependabot in https://github.com/eko/gocache/pull/158
    • Make store options publicly available by @eko in https://github.com/eko/gocache/pull/160

    New Contributors

    • @ralbt made their first contribution in https://github.com/eko/gocache/pull/154

    Full Changelog: https://github.com/eko/gocache/compare/v3.1.0...v3.1.1

    Source code(tar.gz)
    Source code(zip)
  • v3.1.0(Jun 14, 2022)

    What's Changed

    • Bump github.com/stretchr/testify from 1.7.1 to 1.7.2 by @dependabot in https://github.com/eko/gocache/pull/149
    • chain set to run set on all cache stores by @Ashtonian in https://github.com/eko/gocache/pull/146
    • add standard not found error by @Ashtonian in https://github.com/eko/gocache/pull/142
    • Updated error messages to be in lowercase by @eko in https://github.com/eko/gocache/pull/152

    New Contributors

    • @Ashtonian made their first contribution in https://github.com/eko/gocache/pull/146

    Full Changelog: https://github.com/eko/gocache/compare/v3.0.1...v3.1.0

    Source code(tar.gz)
    Source code(zip)
  • v3.0.1(Jun 6, 2022)

    What's Changed

    • Fix Loadable cache NPE when setting loaded value by @braginini in https://github.com/eko/gocache/pull/148

    New Contributors

    • @braginini made their first contribution in https://github.com/eko/gocache/pull/148

    Full Changelog: https://github.com/eko/gocache/compare/v3.0.0...v3.0.1

    Source code(tar.gz)
    Source code(zip)
  • v3.0.0(May 26, 2022)

    What's Changed

    • Reworked options to be variadics by @eko https://github.com/eko/gocache/pull/143
    • Added generics support by @eko in https://github.com/eko/gocache/pull/139

    This version have breaking changes in the 2 following changes:

    Reworked options

    We've updated options to use variadics instead of having a hard options argument at the end and often have to give nil.

    Instead of this:

    err := cacheManager.Set(ctx, "my-key", "my-value", nil)
    

    you will now be able to remove the nil argument:

    err := cacheManager.Set(ctx, "my-key", "my-value")
    

    and if you have some options to pass:

    err := cacheManager.Set(
        ctx,
        "my-key",
        "my-value",
        store.WithExpiration(10 * time.Second),
        store.WithTags([]string{"my-amazing-tag"}),
    )
    

    Generics support

    We have updated code base to use generics: you could still give any, such as the following:

    cacheManager := cache.New[any](redisStore)
    

    or, if you know you will store only a certain object, directly pass it:

    cacheManager := cache.New[*Book](redisStore)
    

    Full Changelog: https://github.com/eko/gocache/compare/v2.3.1...v3.0.0

    Source code(tar.gz)
    Source code(zip)
  • v2.3.1(May 22, 2022)

    What's Changed

    • Updated readme with install instructions by @coolblknerd in https://github.com/eko/gocache/pull/132
    • Bump github.com/smartystreets/assertions from 1.2.1 to 1.13.0 by @dependabot in https://github.com/eko/gocache/pull/133
    • Bump github.com/prometheus/client_golang from 1.12.1 to 1.12.2 by @dependabot in https://github.com/eko/gocache/pull/137
    • Bump github.com/spf13/cast from 1.4.1 to 1.5.0 by @dependabot in https://github.com/eko/gocache/pull/136
    • Make setTags method concurrency-safe by @Magomogo in https://github.com/eko/gocache/pull/138

    New Contributors

    • @coolblknerd made their first contribution in https://github.com/eko/gocache/pull/132
    • @Magomogo made their first contribution in https://github.com/eko/gocache/pull/138

    Full Changelog: https://github.com/eko/gocache/compare/v2.3.0...v2.3.1

    Source code(tar.gz)
    Source code(zip)
  • v2.3.0(Apr 13, 2022)

    What's Changed

    • Bump github.com/prometheus/client_golang from 1.12.0 to 1.12.1 by @dependabot in https://github.com/eko/gocache/pull/125
    • Bump github.com/coocood/freecache from 1.2.0 to 1.2.1 by @dependabot in https://github.com/eko/gocache/pull/128
    • Bump github.com/go-redis/redis/v8 from 8.11.4 to 8.11.5 by @dependabot in https://github.com/eko/gocache/pull/130
    • Bump github.com/stretchr/testify from 1.7.0 to 1.7.1 by @dependabot in https://github.com/eko/gocache/pull/129

    Full Changelog: https://github.com/eko/gocache/compare/v2.2.0...v2.3.0

    Source code(tar.gz)
    Source code(zip)
  • v2.2.0(Jan 23, 2022)

    What's Changed

    • Bump github.com/go-redis/redis/v8 from 8.9.0 to 8.10.0 by @dependabot in https://github.com/eko/gocache/pull/94
    • Bump github.com/dgraph-io/ristretto from 0.0.3 to 0.1.0 by @dependabot in https://github.com/eko/gocache/pull/95
    • mutex on codec to prevent race conditions by @coolka in https://github.com/eko/gocache/pull/97
    • Bump github.com/prometheus/client_golang from 1.10.0 to 1.11.0 by @dependabot in https://github.com/eko/gocache/pull/96
    • Bump github.com/golang/mock from 1.5.0 to 1.6.0 by @dependabot in https://github.com/eko/gocache/pull/98
    • Fix Race Condition in Memcached Store, Close Loadable to Stop Setter Routine by @terev in https://github.com/eko/gocache/pull/100
    • Bump github.com/go-redis/redis/v8 from 8.10.0 to 8.11.0 by @dependabot in https://github.com/eko/gocache/pull/102
    • Add patrickmn/go-cache to README by @Stoakes in https://github.com/eko/gocache/pull/103
    • Bump github.com/go-redis/redis/v8 from 8.11.0 to 8.11.1 by @dependabot in https://github.com/eko/gocache/pull/107
    • Bump github.com/spf13/cast from 1.3.1 to 1.4.0 by @dependabot in https://github.com/eko/gocache/pull/106
    • Bump github.com/go-redis/redis/v8 from 8.11.1 to 8.11.2 by @dependabot in https://github.com/eko/gocache/pull/108
    • fix instanciation typo by @derekperkins in https://github.com/eko/gocache/pull/110
    • Bump github.com/go-redis/redis/v8 from 8.11.2 to 8.11.3 by @dependabot in https://github.com/eko/gocache/pull/109
    • Bump github.com/spf13/cast from 1.4.0 to 1.4.1 by @dependabot in https://github.com/eko/gocache/pull/111
    • Bump github.com/go-redis/redis/v8 from 8.11.3 to 8.11.4 by @dependabot in https://github.com/eko/gocache/pull/112
    • Bumped to go 1.17 by @eko in https://github.com/eko/gocache/pull/113
    • Bump github.com/smartystreets/goconvey from 1.6.4 to 1.6.6 by @dependabot in https://github.com/eko/gocache/pull/115
    • Update LICENSE by @yashmit178 in https://github.com/eko/gocache/pull/116
    • Bump github.com/smartystreets/goconvey from 1.6.6 to 1.6.7 by @dependabot in https://github.com/eko/gocache/pull/117
    • Bump github.com/smartystreets/goconvey from 1.6.7 to 1.7.2 by @dependabot in https://github.com/eko/gocache/pull/119
    • Bump github.com/smartystreets/assertions from 1.2.0 to 1.2.1 by @dependabot in https://github.com/eko/gocache/pull/120
    • Bump github.com/coocood/freecache from 1.1.1 to 1.2.0 by @dependabot in https://github.com/eko/gocache/pull/121
    • Bump github.com/prometheus/client_golang from 1.11.0 to 1.12.0 by @dependabot in https://github.com/eko/gocache/pull/124
    • feat: Support for a key that would implement it's own key generator by @meDavidNS in https://github.com/eko/gocache/pull/123

    New Contributors

    • @coolka made their first contribution in https://github.com/eko/gocache/pull/97
    • @terev made their first contribution in https://github.com/eko/gocache/pull/100
    • @Stoakes made their first contribution in https://github.com/eko/gocache/pull/103
    • @derekperkins made their first contribution in https://github.com/eko/gocache/pull/110
    • @yashmit178 made their first contribution in https://github.com/eko/gocache/pull/116
    • @meDavidNS made their first contribution in https://github.com/eko/gocache/pull/123

    Full Changelog: https://github.com/eko/gocache/compare/v2.1.0...v2.2.0

    Source code(tar.gz)
    Source code(zip)
  • v2.1.0(Jun 1, 2021)

    What's Changed

    • Bump major version by @okhowang in https://github.com/eko/gocache/pull/93
    • Added context to loadFunction by @okhowang in https://github.com/eko/gocache/pull/92

    New Contributors

    • @okhowang made their first contribution in https://github.com/eko/gocache/pull/93

    Full Changelog: https://github.com/eko/gocache/compare/v2.0.0...v2.1.0

    Source code(tar.gz)
    Source code(zip)
  • v2.0.0(May 28, 2021)

    ⚠️ This is a new major release because of API BC break: context was added to all cache methods.

    New Features

    a61fbe3 Added context to cache methods

    Fixes

    4699aca fix: fix cacheManager use error with redis and pegasus

    Other

    b2b1571 Bump github.com/go-redis/redis/v8 from 8.8.3 to 8.9.0 4b757ae Bump github.com/go-redis/redis/v8 from 8.8.2 to 8.8.3 ef7808a Update README.md

    Source code(tar.gz)
    Source code(zip)
  • v1.2.0(May 2, 2021)

    New Features

    6f0b55f Moved from travis-ci to github actions f5dcbee feat: add apache pegasus store

    Fixes

    f2a0586 fix: rebase latest and resolve comment 6ab2bc0 fixed rediscluster_test add context.TODO() aa3f31c fixed rediscluster_test ffd7fde fix: return an error instead panic as a fallback in bigcache store

    Other

    610ce4b Upgrade to GitHub-native Dependabot 6f7b7b8 build(deps): bump github.com/go-redis/redis/v8 from 8.8.0 to 8.8.2 5efb409 docs(readme): add descriptions about how to deal with the returned error from the redis storage ddc81b3 build(deps): bump github.com/go-redis/redis/v8 from 8.7.1 to 8.8.0 afb1aba mr 39e232c 支持 github.com/patrickmn/go-cache 51d1e1a build(deps): bump github.com/prometheus/client_golang 6ff1f44 update redis client to version 8 add redis cluster client tests 26e7da1 build(deps): bump github.com/golang/mock from 1.4.4 to 1.5.0 f23aa7d update bigcache version

    Source code(tar.gz)
    Source code(zip)
  • v1.1.1(Jan 20, 2021)

    New Features

    371ff1e Using simple set redis commands to invalidate tags (#3) 203d229 Replaced the tags csv string by a hset

    Other

    601b20d Ran go mod tidy e82ef1c build(deps): bump github.com/stretchr/testify from 1.6.1 to 1.7.0 30ca7e3 build(deps): bump github.com/prometheus/client_golang 08eee2f Upgraded to go 1.15 and google.golang.org/appengine go v1.6.7

    Source code(tar.gz)
    Source code(zip)
  • v1.1.0(Nov 2, 2020)

    New Features

    a7ab8a7 Implement GetWithTTL for freecache 46a7306 implement interface function f31406a added new store (freecache) ab7dc64 propagate TTL 26e0f71 supporting ristretto ttl

    Fixes

    81bfa26 Removed strings.ToLower on cache key 8adc7b7 remove-log: drop logging in two places a3941db Do not hash key if its type is string 99d5369 fixing tests a9a0f81 doc: fix cache.Options => store.Options e3e61d7 doc: fix bigcache with wrong value type 24c4223 docs: fixed typo in README file 80c1102 Fix redis tags: redis client is returning strings

    Other

    cb3adf2 build(deps): bump github.com/prometheus/client_golang 9e5334e add test for invalid key 5579dbd more tests c36606f Added more tests 1db2250 go mod tidy b1c560c update documentation 0bc17c6 add tests for GetWithTTL 91984f7 tidy go sum 6fd2efd update documentation 0966a70 update tests 3810cba add gitignore 7f5df68 adding more test coverage 5663aac reverting proto support to give as separate PR fa5190f running go mod tidy c76d860 revert go.sum 6e3cd45 test coverage added 5f6b57c build(deps): bump github.com/golang/mock from 1.4.3 to 1.4.4 8fa11e5 build(deps): bump github.com/dgraph-io/ristretto from 0.0.2 to 0.0.3 7d3ab73 build(deps): bump github.com/prometheus/client_golang 497836c build(deps): bump github.com/prometheus/client_golang 0b50739 build(deps): bump github.com/stretchr/testify from 1.6.0 to 1.6.1 ef103e8 build(deps): bump github.com/go-redis/redis/v7 from 7.3.0 to 7.4.0 4d3fd48 build(deps): bump github.com/stretchr/testify from 1.5.1 to 1.6.0 8b9ffef build(deps): bump github.com/go-redis/redis/v7 from 7.2.0 to 7.3.0 70f9205 revert d9c5f5b test with go1.13-issue with using forks in other projects 04e814f build(deps): bump github.com/prometheus/client_golang 3a8bb97 build(deps): bump github.com/prometheus/client_golang b65b9d3 build(deps): bump github.com/golang/mock from 1.4.1 to 1.4.3 9923c46 build(deps): bump github.com/prometheus/client_golang 5ca9b93 Upgrade to go1.14 b85d8c5 build(deps): bump github.com/golang/mock from 1.4.0 to 1.4.1 79b65cf build(deps): bump github.com/go-redis/redis/v7 from 7.1.0 to 7.2.0 c798b07 build(deps): bump github.com/stretchr/testify from 1.4.0 to 1.5.1 3896b7a build(deps): bump github.com/go-redis/redis/v7 from 7.0.1 to 7.1.0 3ab560a build(deps): bump github.com/go-redis/redis/v7 1ce8623 build(deps): bump github.com/prometheus/client_golang a9fa870 build(deps): bump github.com/go-redis/redis/v7 7b615f6 build(deps): bump github.com/prometheus/client_golang 5ded7b2 build(deps): bump github.com/golang/mock from 1.3.1 to 1.4.0 f3f6db0 build(deps): bump github.com/go-redis/redis/v7 edd0dad build(deps): bump github.com/prometheus/client_golang

    Source code(tar.gz)
    Source code(zip)
  • v1.0.0(Dec 8, 2019)

    New Features

    140d01b Using promauto to initialize the metric and testutil in tests 7847237 feat: added Clear() method to flush all cache data 16d5e61 docs: added some store benchmarks

    Fixes

    3b46630 fix(tests): replace mockery by gomock and fix race conditions 19c7bf8 test: rework unit tests to isolate mocks and add missing cases 0627751 style: fixed mispelling words and missing comments

    Other

    2c2e7d2 build(deps): bump github.com/coreos/etcd 871607c build(deps): bump github.com/prometheus/client_golang f9ee181 docs: updated README.md with custom cache/store interfaces 256357e doc: added codecov badge 9de424d ci: added codecov to .travis.yml

    Source code(tar.gz)
    Source code(zip)
  • v0.2.0(Oct 19, 2019)

    New Features

    ff78752 feat: added cache invalidation by tags 238e4ef feat: added cache & store delete() method

    Other

    8de72e9 Added .github files

    Source code(tar.gz)
    Source code(zip)
  • v0.1.0(Oct 15, 2019)

    New Features

    d28a9c2 feat: allow store options override in Set() method 4e751dc feat(store): added bigcache 23439ea feat(cache): added options 7f5503c feat(store): added memcache support

    Fixes

    bd0c5fb fix(README): typo in code example

    Other

    e78581a BREAKING CHANGE: renamed eko/gache to eko/gocache 41b785b docs: added README and travis.yml

    Source code(tar.gz)
    Source code(zip)
Owner
Vincent Composieux
Freelance web architect who loves code and infrastructure. Issue solver around various technologies.
Vincent Composieux
Cache library for golang. It supports expirable Cache, LFU, LRU and ARC.

GCache Cache library for golang. It supports expirable Cache, LFU, LRU and ARC. Features Supports expirable Cache, LFU, LRU and ARC. Goroutine safe. S

Jun Kimura 2k Aug 4, 2022
An in-memory cache library for golang. It supports multiple eviction policies: LRU, LFU, ARC

GCache Cache library for golang. It supports expirable Cache, LFU, LRU and ARC. Features Supports expirable Cache, LFU, LRU and ARC. Goroutine safe. S

Jun Kimura 318 May 31, 2021
cyhone 112 Aug 2, 2022
Package cache is a middleware that provides the cache management for Flamego.

cache Package cache is a middleware that provides the cache management for Flamego. Installation The minimum requirement of Go is 1.16. go get github.

Flamego 11 Jul 14, 2022
A mem cache base on other populator cache, add following feacture

memcache a mem cache base on other populator cache, add following feacture add lazy load(using expired data, and load it asynchronous) add singlefligh

zhq 1 Oct 28, 2021
Cache - A simple cache implementation

Cache A simple cache implementation LRU Cache An in memory cache implementation

Stanislav Petrashov 1 Jan 25, 2022
Gin-cache - Gin cache middleware with golang

Gin-cache - Gin cache middleware with golang

Anson 38 Mar 16, 2022
groupcache is a caching and cache-filling library, intended as a replacement for memcached in many cases.

groupcache Summary groupcache is a distributed caching and cache-filling library, intended as a replacement for a pool of memcached nodes in many case

Go 11.6k Aug 8, 2022
An in-memory key:value store/cache (similar to Memcached) library for Go, suitable for single-machine applications.

go-cache go-cache is an in-memory key:value store/cache similar to memcached that is suitable for applications running on a single machine. Its major

Patrick Mylund Nielsen 6.4k Aug 9, 2022
gdcache is a pure non-intrusive distributed cache library implemented by golang

gdcache is a pure non-intrusive distributed cache library implemented by golang, you can use it to implement your own distributed cache

Jovan 9 Mar 24, 2022
A REST-API service that works as an in memory key-value store with go-minimal-cache library.

A REST-API service that works as an in memory key-value store with go-minimal-cache library.

HarunBuyuktepe 1 Oct 25, 2021
A multi-level cache library with stampede prevention for Go

HybridCache A multi-level cache library with cache stampede prevention for Go import "github.com/cshum/hybridcache" // Redis cache adapter based on R

Adrian Shum 116 May 17, 2022
An in-memory key:value store/cache library written in Go 1.18 generics

go-generics-cache go-generics-cache is an in-memory key:value store/cache that is suitable for applications running on a single machine. This in-memor

Kei Kamikawa 202 Aug 6, 2022
Ristretto - A fast, concurrent cache library built with a focus on performance and correctness

Ristretto Ristretto is a fast, concurrent cache library built with a focus on pe

Koichi Shiraishi 1 Mar 23, 2022
Gocodecache - An in-memory cache library for code value master in Golang

gocodecache An in-memory cache library for code master in Golang. Installation g

Takuo Oki 3 Jun 23, 2022
A zero-dependency cache library for storing data in memory with generics.

Memory Cache A zero-dependency cache library for storing data in memory with generics. Requirements Golang 1.18+ Installation go get -u github.com/rod

Rodrigo Brito 11 May 26, 2022
LevelDB style LRU cache for Go, support non GC object.

Go语言QQ群: 102319854, 1055927514 凹语言(凹读音“Wa”)(The Wa Programming Language): https://github.com/wa-lang/wa LRU Cache Install go get github.com/chai2010/c

chai2010 11 Jul 5, 2020
fastcache - fast thread-safe inmemory cache for big number of entries in Go

Fast thread-safe inmemory cache for big number of entries in Go. Minimizes GC overhead

VictoriaMetrics 1.5k Aug 3, 2022