patrickmn / go-cache

An in-memory key:value store/cache (similar to Memcached) library for Go, suitable for single-machine applications.
https://patrickmn.com/projects/go-cache/
MIT License
8.16k stars 874 forks source link

Cache items gone when re-running script #93

Closed Fyb3roptik closed 5 years ago

Fyb3roptik commented 5 years ago

Here is the code:

c := cache.New(0, 10*time.Minute)
session := &Session{}

// Not set? Set it
if _, found := c.Get(fmt.Sprintf("mykey-%d", iteration)); found == false {
log.Println("DEBUG: SESSION: NOT FOUND")
session = session.Create(somevarshere)
c.Set(fmt.Sprintf("mykey-%d", iteration), session, cache.NoExpiration)
}

if sess, found := c.Get(fmt.Sprintf("mykey-%d", iteration)); found {
  log.Println("DEBUG: FOUND!")
  session = sess.(*Session)
}

Results:

2019/02/08 00:30:29 DEBUG: STARTING ITERATION  1
2019/02/08 00:30:29 DEBUG: SESSION: NOT FOUND

No matter how many times I run the script, it does not find the cache. Should this be stored in memory so when my cronjob runs the script it is able to pull it? Is the cache.New() overriding it?

Fyb3roptik commented 5 years ago

It does work however if I do a Get() right after a Set(), so I know it is working, it is just when I run my script again it is not there

patrickmn commented 5 years ago

I modified your example so that I could run it, and it works as expected:

package main

import (
    "fmt"
    "github.com/patrickmn/go-cache"
    "log"
    "time"
)

type Session struct{
    foo string
}

func (s *Session) Create() *Session {
    return s
}

func main() {
    iteration := 1
    c := cache.New(0, 10*time.Minute)
    session := &Session{}

    // Not set? Set it
    if _, found := c.Get(fmt.Sprintf("mykey-%d", iteration)); found == false {
        log.Println("DEBUG: SESSION: NOT FOUND")
        session = session.Create()
        c.Set(fmt.Sprintf("mykey-%d", iteration), session, cache.NoExpiration)
    }

    if sess, found := c.Get(fmt.Sprintf("mykey-%d", iteration)); found {
        log.Println("DEBUG: FOUND!")
        session = sess.(*Session)
    }
}

Output:

2019/02/07 20:11:37 DEBUG: SESSION: NOT FOUND
2019/02/07 20:11:37 DEBUG: FOUND!

If what you mean is that you are terminating the process and then running it again, then: go-cache is memory-only, and so will disappear when the process exits. If you want disk persistence, you should save and then load the cache using c.SaveFile(fname string) and c.LoadFile(fname string), or, ideally, use the cache in a long-lived process.

Fyb3roptik commented 5 years ago

Yes that is the issue! Your docu says that is deprecated though, so can you give me a working example of doing it that way? Great library BTW!

patrickmn commented 5 years ago

Sure:

items := c.Items()
// serialize using encoding/gob, encoding/json or similar, and write to file

next time:

// deserialize the gob/json file into items
c := c.NewFrom(exp, ci, items)

The deprecated methods basically do exactly this using encoding/gob for serialization/deserialization. Even though the methods are deprecated I'm not likely to ever remove them; they just might not work with certain non-gob.Register()'ed types.

Thank you :) Glad you like it!

Fyb3roptik commented 5 years ago

So do I need to do c.Set and then c.SaveFile?

Fyb3roptik commented 5 years ago

Can you give me an end to end example of it working with SaveFile and LoadFile? It is not working for me

Fyb3roptik commented 5 years ago

@patrickmn I cannot get this to work

yann0917 commented 3 years ago

Can you give me an end to end example of it working with SaveFile and LoadFile? It is not working for me

you need to register gob name use gob.Register(), if not, when you use c.LoadFile() will get error like this gob: name not registered for interface: "xxxx".