Merge pull request #1546 from youngsterxyf/develop

fix #1530
This commit is contained in:
astaxie 2016-01-12 20:01:51 +08:00
commit b90a28bafb
10 changed files with 45 additions and 42 deletions

2
cache/README.md vendored
View File

@ -26,7 +26,7 @@ Then init a Cache (example with memory adapter)
Use it like this: Use it like this:
bm.Put("astaxie", 1, 10) bm.Put("astaxie", 1, 10 * time.Second)
bm.Get("astaxie") bm.Get("astaxie")
bm.IsExist("astaxie") bm.IsExist("astaxie")
bm.Delete("astaxie") bm.Delete("astaxie")

7
cache/cache.go vendored
View File

@ -23,7 +23,7 @@
// //
// Use it like this: // Use it like this:
// //
// bm.Put("astaxie", 1, 10) // bm.Put("astaxie", 1, 10 * time.Second)
// bm.Get("astaxie") // bm.Get("astaxie")
// bm.IsExist("astaxie") // bm.IsExist("astaxie")
// bm.Delete("astaxie") // bm.Delete("astaxie")
@ -33,13 +33,14 @@ package cache
import ( import (
"fmt" "fmt"
"time"
) )
// Cache interface contains all behaviors for cache adapter. // Cache interface contains all behaviors for cache adapter.
// usage: // usage:
// cache.Register("file",cache.NewFileCache) // this operation is run in init method of file.go. // cache.Register("file",cache.NewFileCache) // this operation is run in init method of file.go.
// c,err := cache.NewCache("file","{....}") // c,err := cache.NewCache("file","{....}")
// c.Put("key",value,3600) // c.Put("key",value, 3600 * time.Second)
// v := c.Get("key") // v := c.Get("key")
// //
// c.Incr("counter") // now is 1 // c.Incr("counter") // now is 1
@ -51,7 +52,7 @@ type Cache interface {
// GetMulti is a batch version of Get. // GetMulti is a batch version of Get.
GetMulti(keys []string) []interface{} GetMulti(keys []string) []interface{}
// set cached value with key and expire time. // set cached value with key and expire time.
Put(key string, val interface{}, timeout int64) error Put(key string, val interface{}, timeout time.Duration) error
// delete cached value by key. // delete cached value by key.
Delete(key string) error Delete(key string) error
// increase cached int value by key, as a counter. // increase cached int value by key, as a counter.

16
cache/cache_test.go vendored
View File

@ -25,7 +25,8 @@ func TestCache(t *testing.T) {
if err != nil { if err != nil {
t.Error("init err") t.Error("init err")
} }
if err = bm.Put("astaxie", 1, 10); err != nil { timeoutDuration := 10 * time.Second
if err = bm.Put("astaxie", 1, timeoutDuration); err != nil {
t.Error("set Error", err) t.Error("set Error", err)
} }
if !bm.IsExist("astaxie") { if !bm.IsExist("astaxie") {
@ -42,7 +43,7 @@ func TestCache(t *testing.T) {
t.Error("check err") t.Error("check err")
} }
if err = bm.Put("astaxie", 1, 10); err != nil { if err = bm.Put("astaxie", 1, timeoutDuration); err != nil {
t.Error("set Error", err) t.Error("set Error", err)
} }
@ -67,7 +68,7 @@ func TestCache(t *testing.T) {
} }
//test GetMulti //test GetMulti
if err = bm.Put("astaxie", "author", 10); err != nil { if err = bm.Put("astaxie", "author", timeoutDuration); err != nil {
t.Error("set Error", err) t.Error("set Error", err)
} }
if !bm.IsExist("astaxie") { if !bm.IsExist("astaxie") {
@ -77,7 +78,7 @@ func TestCache(t *testing.T) {
t.Error("get err") t.Error("get err")
} }
if err = bm.Put("astaxie1", "author1", 10); err != nil { if err = bm.Put("astaxie1", "author1", timeoutDuration); err != nil {
t.Error("set Error", err) t.Error("set Error", err)
} }
if !bm.IsExist("astaxie1") { if !bm.IsExist("astaxie1") {
@ -101,7 +102,8 @@ func TestFileCache(t *testing.T) {
if err != nil { if err != nil {
t.Error("init err") t.Error("init err")
} }
if err = bm.Put("astaxie", 1, 10); err != nil { timeoutDuration := 10 * time.Second
if err = bm.Put("astaxie", 1, timeoutDuration); err != nil {
t.Error("set Error", err) t.Error("set Error", err)
} }
if !bm.IsExist("astaxie") { if !bm.IsExist("astaxie") {
@ -133,7 +135,7 @@ func TestFileCache(t *testing.T) {
} }
//test string //test string
if err = bm.Put("astaxie", "author", 10); err != nil { if err = bm.Put("astaxie", "author", timeoutDuration); err != nil {
t.Error("set Error", err) t.Error("set Error", err)
} }
if !bm.IsExist("astaxie") { if !bm.IsExist("astaxie") {
@ -144,7 +146,7 @@ func TestFileCache(t *testing.T) {
} }
//test GetMulti //test GetMulti
if err = bm.Put("astaxie1", "author1", 10); err != nil { if err = bm.Put("astaxie1", "author1", timeoutDuration); err != nil {
t.Error("set Error", err) t.Error("set Error", err)
} }
if !bm.IsExist("astaxie1") { if !bm.IsExist("astaxie1") {

18
cache/file.go vendored
View File

@ -33,8 +33,8 @@ import (
// it contains data and expire time. // it contains data and expire time.
type FileCacheItem struct { type FileCacheItem struct {
Data interface{} Data interface{}
Lastaccess int64 Lastaccess time.Time
Expired int64 Expired time.Time
} }
// FileCache Config // FileCache Config
@ -42,7 +42,7 @@ var (
FileCachePath = "cache" // cache directory FileCachePath = "cache" // cache directory
FileCacheFileSuffix = ".bin" // cache file suffix FileCacheFileSuffix = ".bin" // cache file suffix
FileCacheDirectoryLevel = 2 // cache file deep level if auto generated cache files. FileCacheDirectoryLevel = 2 // cache file deep level if auto generated cache files.
FileCacheEmbedExpiry int64 // cache expire time, default is no expire forever. FileCacheEmbedExpiry time.Duration = 0 // cache expire time, default is no expire forever.
) )
// FileCache is cache adapter for file storage. // FileCache is cache adapter for file storage.
@ -76,7 +76,7 @@ func (fc *FileCache) StartAndGC(config string) error {
cfg["DirectoryLevel"] = strconv.Itoa(FileCacheDirectoryLevel) cfg["DirectoryLevel"] = strconv.Itoa(FileCacheDirectoryLevel)
} }
if _, ok := cfg["EmbedExpiry"]; !ok { if _, ok := cfg["EmbedExpiry"]; !ok {
cfg["EmbedExpiry"] = strconv.FormatInt(FileCacheEmbedExpiry, 10) cfg["EmbedExpiry"] = strconv.FormatInt(int64(FileCacheEmbedExpiry.Seconds()), 10)
} }
fc.CachePath = cfg["CachePath"] fc.CachePath = cfg["CachePath"]
fc.FileSuffix = cfg["FileSuffix"] fc.FileSuffix = cfg["FileSuffix"]
@ -123,7 +123,7 @@ func (fc *FileCache) Get(key string) interface{} {
} }
var to FileCacheItem var to FileCacheItem
GobDecode(fileData, &to) GobDecode(fileData, &to)
if to.Expired < time.Now().Unix() { if to.Expired.Before(time.Now()) {
return "" return ""
} }
return to.Data return to.Data
@ -142,16 +142,16 @@ func (fc *FileCache) GetMulti(keys []string) []interface{} {
// Put value into file cache. // Put value into file cache.
// timeout means how long to keep this file, unit of ms. // timeout means how long to keep this file, unit of ms.
// if timeout equals FileCacheEmbedExpiry(default is 0), cache this item forever. // if timeout equals FileCacheEmbedExpiry(default is 0), cache this item forever.
func (fc *FileCache) Put(key string, val interface{}, timeout int64) error { func (fc *FileCache) Put(key string, val interface{}, timeout time.Duration) error {
gob.Register(val) gob.Register(val)
item := FileCacheItem{Data: val} item := FileCacheItem{Data: val}
if timeout == FileCacheEmbedExpiry { if timeout == FileCacheEmbedExpiry {
item.Expired = time.Now().Unix() + (86400 * 365 * 10) // ten years item.Expired = time.Now().Add((86400 * 365 * 10) * time.Second) // ten years
} else { } else {
item.Expired = time.Now().Unix() + timeout item.Expired = time.Now().Add(timeout)
} }
item.Lastaccess = time.Now().Unix() item.Lastaccess = time.Now()
data, err := GobEncode(item) data, err := GobEncode(item)
if err != nil { if err != nil {
return err return err

View File

@ -37,6 +37,7 @@ import (
"github.com/bradfitz/gomemcache/memcache" "github.com/bradfitz/gomemcache/memcache"
"github.com/astaxie/beego/cache" "github.com/astaxie/beego/cache"
"time"
) )
// Cache Memcache adapter. // Cache Memcache adapter.
@ -89,7 +90,7 @@ func (rc *Cache) GetMulti(keys []string) []interface{} {
} }
// Put put value to memcache. only support string. // Put put value to memcache. only support string.
func (rc *Cache) Put(key string, val interface{}, timeout int64) error { func (rc *Cache) Put(key string, val interface{}, timeout time.Duration) error {
if rc.conn == nil { if rc.conn == nil {
if err := rc.connectInit(); err != nil { if err := rc.connectInit(); err != nil {
return err return err
@ -99,7 +100,7 @@ func (rc *Cache) Put(key string, val interface{}, timeout int64) error {
if !ok { if !ok {
return errors.New("val must string") return errors.New("val must string")
} }
item := memcache.Item{Key: key, Value: []byte(v), Expiration: int32(timeout)} item := memcache.Item{Key: key, Value: []byte(v), Expiration: int32(timeout/time.Second)}
return rc.conn.Set(&item) return rc.conn.Set(&item)
} }

View File

@ -28,7 +28,8 @@ func TestMemcacheCache(t *testing.T) {
if err != nil { if err != nil {
t.Error("init err") t.Error("init err")
} }
if err = bm.Put("astaxie", "1", 10); err != nil { timeoutDuration := 10 * time.Second
if err = bm.Put("astaxie", "1", timeoutDuration); err != nil {
t.Error("set Error", err) t.Error("set Error", err)
} }
if !bm.IsExist("astaxie") { if !bm.IsExist("astaxie") {
@ -40,7 +41,7 @@ func TestMemcacheCache(t *testing.T) {
if bm.IsExist("astaxie") { if bm.IsExist("astaxie") {
t.Error("check err") t.Error("check err")
} }
if err = bm.Put("astaxie", "1", 10); err != nil { if err = bm.Put("astaxie", "1", timeoutDuration); err != nil {
t.Error("set Error", err) t.Error("set Error", err)
} }
@ -69,7 +70,7 @@ func TestMemcacheCache(t *testing.T) {
} }
//test string //test string
if err = bm.Put("astaxie", "author", 10); err != nil { if err = bm.Put("astaxie", "author", timeoutDuration); err != nil {
t.Error("set Error", err) t.Error("set Error", err)
} }
if !bm.IsExist("astaxie") { if !bm.IsExist("astaxie") {
@ -81,7 +82,7 @@ func TestMemcacheCache(t *testing.T) {
} }
//test GetMulti //test GetMulti
if err = bm.Put("astaxie1", "author1", 10); err != nil { if err = bm.Put("astaxie1", "author1", timeoutDuration); err != nil {
t.Error("set Error", err) t.Error("set Error", err)
} }
if !bm.IsExist("astaxie1") { if !bm.IsExist("astaxie1") {

12
cache/memory.go vendored
View File

@ -17,7 +17,6 @@ package cache
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt"
"sync" "sync"
"time" "time"
) )
@ -31,7 +30,7 @@ var (
type MemoryItem struct { type MemoryItem struct {
val interface{} val interface{}
createdTime time.Time createdTime time.Time
lifespan int64 lifespan time.Duration
} }
func (mi *MemoryItem) isExpire() bool { func (mi *MemoryItem) isExpire() bool {
@ -39,7 +38,7 @@ func (mi *MemoryItem) isExpire() bool {
if mi.lifespan == 0 { if mi.lifespan == 0 {
return false return false
} }
return time.Now().Unix()-mi.createdTime.Unix() > mi.lifespan return time.Now().Sub(mi.createdTime) > mi.lifespan
} }
// MemoryCache is Memory cache adapter. // MemoryCache is Memory cache adapter.
@ -83,7 +82,7 @@ func (bc *MemoryCache) GetMulti(names []string) []interface{} {
// Put cache to memory. // Put cache to memory.
// if lifespan is 0, it will be forever till restart. // if lifespan is 0, it will be forever till restart.
func (bc *MemoryCache) Put(name string, value interface{}, lifespan int64) error { func (bc *MemoryCache) Put(name string, value interface{}, lifespan time.Duration) error {
bc.Lock() bc.Lock()
defer bc.Unlock() defer bc.Unlock()
bc.items[name] = &MemoryItem{ bc.items[name] = &MemoryItem{
@ -201,10 +200,7 @@ func (bc *MemoryCache) StartAndGC(config string) error {
cf = make(map[string]int) cf = make(map[string]int)
cf["interval"] = DefaultEvery cf["interval"] = DefaultEvery
} }
dur, err := time.ParseDuration(fmt.Sprintf("%ds", cf["interval"])) dur := time.Duration(cf["interval"]) * time.Second
if err != nil {
return err
}
bc.Every = cf["interval"] bc.Every = cf["interval"]
bc.dur = dur bc.dur = dur
go bc.vaccuum() go bc.vaccuum()

View File

@ -109,9 +109,9 @@ ERROR:
} }
// Put put cache to redis. // Put put cache to redis.
func (rc *Cache) Put(key string, val interface{}, timeout int64) error { func (rc *Cache) Put(key string, val interface{}, timeout time.Duration) error {
var err error var err error
if _, err = rc.do("SETEX", key, timeout, val); err != nil { if _, err = rc.do("SETEX", key, int64(timeout/time.Second), val); err != nil {
return err return err
} }

View File

@ -28,7 +28,8 @@ func TestRedisCache(t *testing.T) {
if err != nil { if err != nil {
t.Error("init err") t.Error("init err")
} }
if err = bm.Put("astaxie", 1, 10); err != nil { timeoutDuration := 10 * time.Second
if err = bm.Put("astaxie", 1, timeoutDuration); err != nil {
t.Error("set Error", err) t.Error("set Error", err)
} }
if !bm.IsExist("astaxie") { if !bm.IsExist("astaxie") {
@ -40,7 +41,7 @@ func TestRedisCache(t *testing.T) {
if bm.IsExist("astaxie") { if bm.IsExist("astaxie") {
t.Error("check err") t.Error("check err")
} }
if err = bm.Put("astaxie", 1, 10); err != nil { if err = bm.Put("astaxie", 1, timeoutDuration); err != nil {
t.Error("set Error", err) t.Error("set Error", err)
} }
@ -69,7 +70,7 @@ func TestRedisCache(t *testing.T) {
} }
//test string //test string
if err = bm.Put("astaxie", "author", 10); err != nil { if err = bm.Put("astaxie", "author", timeoutDuration); err != nil {
t.Error("set Error", err) t.Error("set Error", err)
} }
if !bm.IsExist("astaxie") { if !bm.IsExist("astaxie") {
@ -81,7 +82,7 @@ func TestRedisCache(t *testing.T) {
} }
//test GetMulti //test GetMulti
if err = bm.Put("astaxie1", "author1", 10); err != nil { if err = bm.Put("astaxie1", "author1", timeoutDuration); err != nil {
t.Error("set Error", err) t.Error("set Error", err)
} }
if !bm.IsExist("astaxie1") { if !bm.IsExist("astaxie1") {

View File

@ -64,6 +64,7 @@ import (
"net/http" "net/http"
"path" "path"
"strings" "strings"
"time"
"github.com/astaxie/beego" "github.com/astaxie/beego"
"github.com/astaxie/beego/cache" "github.com/astaxie/beego/cache"
@ -78,7 +79,7 @@ var (
const ( const (
// default captcha attributes // default captcha attributes
challengeNums = 6 challengeNums = 6
expiration = 600 expiration = 600 * time.Second
fieldIDName = "captcha_id" fieldIDName = "captcha_id"
fieldCaptchaName = "captcha" fieldCaptchaName = "captcha"
cachePrefix = "captcha_" cachePrefix = "captcha_"
@ -106,7 +107,7 @@ type Captcha struct {
ChallengeNums int ChallengeNums int
// captcha expiration seconds // captcha expiration seconds
Expiration int64 Expiration time.Duration
// cache key prefix // cache key prefix
CachePrefix string CachePrefix string