Memory Cache Papers of Problems Easily Neglected in Beego

Keywords: Go JSON Redis

Preface

When I blog based on beego, I encountered a strange problem: when using Memory Cache type caching, it's strange that the caching doesn't work, but it's okay to use redis. Because of the time problem, I didn't go deep into it. After all, at that time, I would actually use Memory as a cache. So I put it down, and today someone in the group asked the same question. I decided to study the pit.

Let's start with an example.

Set Cache code:

var (
    urlcache cache.Cache
)

func init() {
    urlcache, _ = cache.NewCache("memory", `{"interval":10}`)
}


func (this *SetController) Get() {
        urlcache.Put("test", "test result sada", 60)
}

Get Cache code:

func (this *GetController) Get() {

    result := urlcache.Get("test")

    this.Data["json"] = result
    this.ServeJSON()
}

First, let's look at the outcome. What do you think is the result of output?

Yes, the result is:

null

So let's look at another example:

Set Cache code:

var (
    urlcache cache.Cache
)

func init() {
    urlcache, _ = cache.NewCache("memory", `{"interval":10}`)
}


func (this *SetController) Get() {
        urlcache.Put("test", "test result sada", 0)
}

Get Cache code:

func (this *GetController) Get() {

    result := urlcache.Get("test")

    this.Data["json"] = result
    this.ServeJSON()
}

And guess what the result is.

As you may all know, the result is:

test result sada

Why is it so? There is only one truth!

The third parameter of this Put is time.Duration is the time unit of GC setting memory. So when we set this time directly, we often neglect that the unit only writes a number. So when we finally go back to fetch the cache, the cache has already expired.
This tells us that we must be careful when looking at documents. Let me post the document and the Cache source code:

The official document gives the interface:

type Cache interface {
    Get(key string) interface{}
    GetMulti(keys []string) []interface{}
    Put(key string, val interface{}, timeout time.Duration) error
    Delete(key string) error
    Incr(key string) error
    Decr(key string) error
    IsExist(key string) bool
    ClearAll() error
    StartAndGC(config string) error
}

Memor.go source code:

// Put cache to memory.
// if lifespan is 0, it will be forever till restart.
func (bc *MemoryCache) Put(name string, value interface{}, lifespan time.Duration) error {
    bc.Lock()
    defer bc.Unlock()
    bc.items[name] = &MemoryItem{
        val:         value,
        createdTime: time.Now(),
        lifespan:    lifespan,
    }
    return nil
}

Welcome friends to leave comments and learn to communicate with each other.

Click on me to read the original text

Posted by Lord Sauron on Mon, 30 Sep 2019 01:32:45 -0700