eko / gocache

☔️ A complete Go cache library that brings you multiple ways of managing your caches
https://vincent.composieux.fr/article/i-wrote-gocache-a-complete-and-extensible-go-cache-library/
MIT License
2.4k stars 193 forks source link

Cannot use go-cache as backend cache for cache.NewMetric #236

Open zclyne opened 6 months ago

zclyne commented 6 months ago

Hi, I was trying to use go-cache as a backend cache for a cache with prometheus metrics. I expose the prometheus metrics via http localhost:8080/metrics but this endpoint returns empty response, i.e. no metrics.

Steps for Reproduction

ctx := context.Background()

// initialize backend go-cache store
gocacheClient := gocache.New(5*time.Minute, 10*time.Minute)
gocacheStore := gocache_store.NewGoCache(gocacheClient)

// initialize prometheus metrics store
registry := prometheus.NewRegistry()
promMetrics := metrics.NewPrometheus("my-test-app", metrics.WithRegisterer(registry))

// initialize cache with metrics
cacheManager := cache.NewMetric[any](promMetrics, gocacheStore)
err := cacheManager.Set(ctx, "my-key", []byte("my-value"))

value, err := cacheManager.Get(ctx, "my-key")
fmt.Printf("%s", value)

After inspecting the code I found that gocacheStore doesn't implement the SetterCacheInterface interface, which causes switch...case... miss defined in the function below https://github.com/eko/gocache/blob/96fc2f790c4cfb27659863657625fa8c4e68d25d/lib/cache/metric.go#L63-L73

Expected behavior: metrics should be updated and collected by the prometheus registry

Actual behavior: no metrics collected

Platforms:

Go: 1.20 Linux: 3.10.0-1160.105.1.el7.x86_64

Versions:

github.com/eko/gocache/lib/v4 v4.1.5 github.com/eko/gocache/store/go_cache/v4 v4.2.1

If fixing this issue will be on the roadmap, I can help contribute. Thanks!

lypro09539 commented 6 months ago

cacheManager := cache.NewMetric[any](promMetrics, gocacheStore)

这行错了,应该

cacheManager := cache.NewMetric[any](promMetrics, cache.New[any](gocacheStore))
zclyne commented 6 months ago

It is working fine now. Thank you so much!

It seems that goCacheStore object implements the StoreInterface interface while NewMetric takes a CacheInterface, but StoreInferface happens to implement CacheInterface, therefore the compiler is happy with it but in fact it is wrong in terms of program logic. I wonder if we can separate these two interfaces in case people run into issues like this again?

Apologies that I don't have Chinese input on this computer. I appreciate your help!