1 // Copyright (c) 2012-2016 The Revel Framework Authors, All rights reserved.
2 // Revel Framework source code and usage is governed by a MIT style
3 // license that can be found in the LICENSE file.
11 "github.com/bradfitz/gomemcache/memcache"
12 "github.com/revel/revel/logger"
15 // MemcachedCache wraps the Memcached client to meet the Cache interface.
16 type MemcachedCache struct {
18 defaultExpiration time.Duration
21 func NewMemcachedCache(hostList []string, defaultExpiration time.Duration) MemcachedCache {
22 return MemcachedCache{memcache.New(hostList...), defaultExpiration}
25 func (c MemcachedCache) Set(key string, value interface{}, expires time.Duration) error {
26 return c.invoke((*memcache.Client).Set, key, value, expires)
29 func (c MemcachedCache) Add(key string, value interface{}, expires time.Duration) error {
30 return c.invoke((*memcache.Client).Add, key, value, expires)
33 func (c MemcachedCache) Replace(key string, value interface{}, expires time.Duration) error {
34 return c.invoke((*memcache.Client).Replace, key, value, expires)
37 func (c MemcachedCache) Get(key string, ptrValue interface{}) error {
38 item, err := c.Client.Get(key)
40 return convertMemcacheError(err)
42 return Deserialize(item.Value, ptrValue)
45 func (c MemcachedCache) GetMulti(keys ...string) (Getter, error) {
46 items, err := c.Client.GetMulti(keys)
48 return nil, convertMemcacheError(err)
50 return ItemMapGetter(items), nil
53 func (c MemcachedCache) Delete(key string) error {
54 return convertMemcacheError(c.Client.Delete(key))
57 func (c MemcachedCache) Increment(key string, delta uint64) (newValue uint64, err error) {
58 newValue, err = c.Client.Increment(key, delta)
59 return newValue, convertMemcacheError(err)
62 func (c MemcachedCache) Decrement(key string, delta uint64) (newValue uint64, err error) {
63 newValue, err = c.Client.Decrement(key, delta)
64 return newValue, convertMemcacheError(err)
67 func (c MemcachedCache) Flush() error {
68 err := errors.New("Flush: can not flush memcached")
69 cacheLog.Error(err.Error())
73 func (c MemcachedCache) invoke(f func(*memcache.Client, *memcache.Item) error,
74 key string, value interface{}, expires time.Duration) error {
77 case DefaultExpiryTime:
78 expires = c.defaultExpiration
79 case ForEverNeverExpiry:
80 expires = time.Duration(0)
83 b, err := Serialize(value)
87 return convertMemcacheError(f(c.Client, &memcache.Item{
90 Expiration: int32(expires / time.Second),
94 // ItemMapGetter implements a Getter on top of the returned item map.
95 type ItemMapGetter map[string]*memcache.Item
97 func (g ItemMapGetter) Get(key string, ptrValue interface{}) error {
103 return Deserialize(item.Value, ptrValue)
106 func convertMemcacheError(err error) error {
110 case memcache.ErrCacheMiss:
112 case memcache.ErrNotStored:
116 cacheLog.Error("convertMemcacheError:", "error", err, "trace", logger.NewCallStack())