github.com/keysonzzz/kmg@v0.0.0-20151121023212-05317bfd7d39/kmgCache/FileTtlCache.go (about) 1 package kmgCache 2 3 import ( 4 "encoding/hex" 5 "path/filepath" 6 "time" 7 8 "github.com/bronze1man/kmg/encoding/kmgGob" 9 "github.com/bronze1man/kmg/kmgConfig" 10 "github.com/bronze1man/kmg/kmgFile" 11 ) 12 13 type ttlCacheEntryV2 struct { 14 Value []byte 15 Timeout time.Time 16 } 17 18 func getFileTtlCachePath(key string) string { 19 return filepath.Join(kmgConfig.DefaultEnv().TmpPath, "FileTtlCache", hex.EncodeToString([]byte(key))) 20 } 21 22 // 文件ttl缓存实现,每次都会读取文件,由于没有泛型,此处需要调用者自行解决序列化问题. 23 // 2.存储在文件里面,以便重启之后可以使用. 24 // 3.当缓存存在的时候,并且ttl在时间范围内,使用ttl,当缓存不存在的时候,使用回调拉取数据.当缓存过期的时候,使用回调拉取数据. 25 // 4.每一次使用都会读取文件 26 // 5.当某一次缓存拉取出现错误的时候,直接返回错误给调用者 27 func FileTtlCache(key string, f func() (b []byte, ttl time.Duration, err error)) (b []byte, err error) { 28 entry := ttlCacheEntryV2{} 29 cacheFilePath := getFileTtlCachePath(key) 30 now := time.Now() 31 err = kmgGob.ReadFile(cacheFilePath, &entry) 32 if err == nil && entry.Timeout.After(now) { 33 return entry.Value, nil 34 } 35 b, ttl, err := f() 36 if err != nil { 37 return nil, err 38 } 39 entry.Value = b 40 entry.Timeout = now.Add(ttl) 41 err = kmgFile.MkdirForFile(cacheFilePath) 42 if err != nil { 43 return nil, err 44 } 45 err = kmgGob.WriteFile(cacheFilePath, entry) 46 if err != nil { 47 return nil, err 48 } 49 return b, nil 50 }