Skip to content

Commit f5c9db9

Browse files
authored
Merge pull request revel#1219 from notzippy/cache_update
Updated to patrickmn/go-cache, current robfig dependency was behind.
2 parents 18479bc + 9381cef commit f5c9db9

File tree

2 files changed

+93
-19
lines changed

2 files changed

+93
-19
lines changed

cache/cache.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,9 @@ type Cache interface {
121121
var (
122122
Instance Cache
123123

124-
ErrCacheMiss = errors.New("revel/cache: key not found")
125-
ErrNotStored = errors.New("revel/cache: not stored")
124+
ErrCacheMiss = errors.New("revel/cache: key not found")
125+
ErrNotStored = errors.New("revel/cache: not stored")
126+
ErrInvalidValue = errors.New("revel/cache: invalid value")
126127
)
127128

128129
// The package implements the Cache interface (as sugar).

cache/inmemory.go

Lines changed: 90 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,25 @@ import (
99
"reflect"
1010
"time"
1111

12+
"github.com/patrickmn/go-cache"
1213
"github.com/revel/revel"
13-
"github.com/robfig/go-cache"
14+
"sync"
1415
)
1516

1617
type InMemoryCache struct {
17-
cache.Cache
18+
cache cache.Cache // Only expose the methods we want to make available
19+
mu sync.RWMutex // For increment / decrement prevent reads and writes
1820
}
1921

2022
func NewInMemoryCache(defaultExpiration time.Duration) InMemoryCache {
21-
return InMemoryCache{*cache.New(defaultExpiration, time.Minute)}
23+
return InMemoryCache{cache: *cache.New(defaultExpiration, time.Minute), mu: sync.RWMutex{}}
2224
}
2325

2426
func (c InMemoryCache) Get(key string, ptrValue interface{}) error {
25-
value, found := c.Cache.Get(key)
27+
c.mu.RLock()
28+
defer c.mu.RUnlock()
29+
30+
value, found := c.cache.Get(key)
2631
if !found {
2732
return ErrCacheMiss
2833
}
@@ -43,50 +48,118 @@ func (c InMemoryCache) GetMulti(keys ...string) (Getter, error) {
4348
}
4449

4550
func (c InMemoryCache) Set(key string, value interface{}, expires time.Duration) error {
51+
c.mu.Lock()
52+
defer c.mu.Unlock()
4653
// NOTE: go-cache understands the values of DefaultExpiryTime and ForEverNeverExpiry
47-
c.Cache.Set(key, value, expires)
54+
c.cache.Set(key, value, expires)
4855
return nil
4956
}
5057

5158
func (c InMemoryCache) Add(key string, value interface{}, expires time.Duration) error {
52-
err := c.Cache.Add(key, value, expires)
53-
if err == cache.ErrKeyExists {
59+
c.mu.Lock()
60+
defer c.mu.Unlock()
61+
err := c.cache.Add(key, value, expires)
62+
if err != nil {
5463
return ErrNotStored
5564
}
5665
return err
5766
}
5867

5968
func (c InMemoryCache) Replace(key string, value interface{}, expires time.Duration) error {
60-
if err := c.Cache.Replace(key, value, expires); err != nil {
69+
c.mu.Lock()
70+
defer c.mu.Unlock()
71+
if err := c.cache.Replace(key, value, expires); err != nil {
6172
return ErrNotStored
6273
}
6374
return nil
6475
}
6576

6677
func (c InMemoryCache) Delete(key string) error {
67-
if found := c.Cache.Delete(key); !found {
78+
c.mu.RLock()
79+
defer c.mu.RUnlock()
80+
if _, found := c.cache.Get(key); !found {
6881
return ErrCacheMiss
6982
}
83+
c.cache.Delete(key)
7084
return nil
7185
}
7286

7387
func (c InMemoryCache) Increment(key string, n uint64) (newValue uint64, err error) {
74-
newValue, err = c.Cache.Increment(key, n)
75-
if err == cache.ErrCacheMiss {
88+
c.mu.Lock()
89+
defer c.mu.Unlock()
90+
if _, found := c.cache.Get(key); !found {
7691
return 0, ErrCacheMiss
7792
}
78-
return
93+
if err = c.cache.Increment(key, int64(n)); err != nil {
94+
return
95+
}
96+
97+
return c.convertTypeToUint64(key)
7998
}
8099

81100
func (c InMemoryCache) Decrement(key string, n uint64) (newValue uint64, err error) {
82-
newValue, err = c.Cache.Decrement(key, n)
83-
if err == cache.ErrCacheMiss {
84-
return 0, ErrCacheMiss
101+
c.mu.Lock()
102+
defer c.mu.Unlock()
103+
if nv,err := c.convertTypeToUint64(key);err !=nil {
104+
return 0, err
105+
} else {
106+
// Stop from going below zero
107+
if n>nv {
108+
n=nv
109+
}
85110
}
86-
return
111+
if err = c.cache.Decrement(key, int64(n)); err != nil {
112+
return
113+
}
114+
115+
return c.convertTypeToUint64(key)
87116
}
88117

89118
func (c InMemoryCache) Flush() error {
90-
c.Cache.Flush()
119+
c.mu.Lock()
120+
defer c.mu.Unlock()
121+
122+
c.cache.Flush()
91123
return nil
92124
}
125+
126+
// Fetches and returns the converted type to a uint64
127+
func (c InMemoryCache) convertTypeToUint64(key string) (newValue uint64, err error) {
128+
v, found := c.cache.Get(key)
129+
if !found {
130+
return newValue, ErrCacheMiss
131+
}
132+
133+
switch v.(type) {
134+
case int:
135+
newValue = uint64(v.(int))
136+
case int8:
137+
newValue = uint64(v.(int8))
138+
case int16:
139+
newValue = uint64(v.(int16))
140+
case int32:
141+
newValue = uint64(v.(int32))
142+
case int64:
143+
newValue = uint64(v.(int64))
144+
case uint:
145+
newValue = uint64(v.(uint))
146+
case uintptr:
147+
newValue = uint64(v.(uintptr))
148+
case uint8:
149+
newValue = uint64(v.(uint8))
150+
case uint16:
151+
newValue = uint64(v.(uint16))
152+
case uint32:
153+
newValue = uint64(v.(uint32))
154+
case uint64:
155+
newValue = uint64(v.(uint64))
156+
case float32:
157+
newValue = uint64(v.(float32))
158+
case float64:
159+
newValue = uint64(v.(float64))
160+
default:
161+
err = ErrInvalidValue
162+
}
163+
return
164+
}
165+

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy