Skip to content

Commit 991903d

Browse files
authored
Merge pull request #4 from thinkoner/develop
Added cache
2 parents f3e191b + e2619b0 commit 991903d

11 files changed

+996
-1
lines changed

.travis.yml

+18-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,21 @@
11
language: go
22

3+
sudo: false
4+
35
go:
4-
- "1.x"
6+
- 1.6.x
7+
- 1.7.x
8+
- 1.8.x
9+
- 1.9.x
10+
- 1.10.x
11+
- 1.11.x
12+
- master
13+
14+
services:
15+
- redis-server
16+
17+
before_install:
18+
- go get github.com/mattn/goveralls
19+
20+
script:
21+
- $HOME/gopath/bin/goveralls -service=travis-ci

cache/README.md

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# ThinkGo-Cache
2+
3+
`ThinkGo-Cache` is a cache library for Golang,it currently supports redis, memory, and can customize the store adapter.
4+
5+
## Installation
6+
7+
```
8+
go get github.com/thinkoner/thinkgo/cache
9+
```
10+
11+
## Usage
12+
13+
#### Basic Usage
14+
15+
```go
16+
import (
17+
"github.com/thinkoner/thinkgo/cache"
18+
"time"
19+
)
20+
21+
22+
var foo string
23+
24+
// Create a cache with memory store
25+
c, _ := cache.Cache(cache.NewMemoryStore("thinkgo"))
26+
27+
// Set the value
28+
c.Put("foo", "thinkgo", 10 * time.Minute)
29+
30+
// Get the string associated with the key "foo" from the cache
31+
c.Get("foo", &foo)
32+
33+
```
34+
35+
#### Retrieve & Store
36+
37+
Sometimes you may wish to retrieve an item from the cache, but also store a default value if the requested item doesn't exist. For example, you may wish to retrieve all users from the cache or, if they don't exist, retrieve them from the callback and add them to the cache. You may do this using the `Remember` method:
38+
39+
```go
40+
var foo int
41+
42+
cache.Remember("foo", &a, 1*time.Minute, func() interface{} {
43+
return "thinkgo"
44+
})
45+
```
46+
47+
## License
48+
49+
This project is licensed under the `Apache 2.0 license`.

cache/cache.go

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package cache
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
)
7+
8+
var adapters = make(map[string]Store)
9+
10+
// Register Register a cache adapter available by the adapter name.
11+
func Register(name string, adapter Store) error {
12+
if adapter == nil {
13+
return errors.New("cache: Register adapter is nil")
14+
}
15+
if _, ok := adapters[name]; ok {
16+
return errors.New("cache: Register called twice for adapter " + name)
17+
}
18+
adapters[name] = adapter
19+
return nil
20+
}
21+
22+
// NewCache Create a new cache by adapter name.
23+
func Cache(adapter interface{}) (*Repository, error) {
24+
var store Store
25+
switch adapter.(type) {
26+
case string:
27+
var ok bool
28+
store, ok = adapters[adapter.(string)]
29+
if !ok {
30+
err := fmt.Errorf("cache: unknown adapter name %q (forgot to import?)", adapter.(string))
31+
return nil, err
32+
}
33+
case Store:
34+
store = adapter.(Store)
35+
}
36+
37+
return NewRepository(store), nil
38+
}

cache/cache_test.go

+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
package cache
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
"time"
7+
8+
"github.com/gomodule/redigo/redis"
9+
)
10+
11+
func testCache(t *testing.T, cache *Repository) {
12+
var a int
13+
var b string
14+
err := cache.Get("a", &a)
15+
if err == nil {
16+
t.Error("Getting A found value that shouldn't exist:", a)
17+
}
18+
19+
err = cache.Get("b", &b)
20+
if err == nil {
21+
t.Error("Getting B found value that shouldn't exist:", b)
22+
}
23+
24+
cache.Put("a", 1, 10*time.Minute)
25+
cache.Put("b", "thinkgo", 10*time.Minute)
26+
27+
err = cache.Get("a", &a)
28+
if err != nil {
29+
t.Error(err)
30+
}
31+
32+
if a != 1 {
33+
t.Error("Expect: ", 1)
34+
}
35+
36+
err = cache.Get("b", &b)
37+
if err != nil {
38+
t.Error(err)
39+
}
40+
41+
if b != "thinkgo" {
42+
t.Error("Expect: ", "thinkgo")
43+
}
44+
45+
testCacheRemember(t, cache)
46+
}
47+
48+
func testCacheRemember(t *testing.T, cache *Repository) {
49+
cache.Clear()
50+
51+
var a int
52+
53+
err := cache.Remember("a", &a, 1*time.Minute, func() interface{} {
54+
return 1
55+
})
56+
57+
if err != nil {
58+
t.Error(err)
59+
}
60+
61+
if a != 1 {
62+
t.Error(fmt.Sprintf("Expect: %d, Actual: %d ", 1, a))
63+
}
64+
65+
err = cache.Remember("a", &a, 1*time.Minute, func() interface{} {
66+
return 2
67+
})
68+
69+
if err != nil {
70+
t.Error(err)
71+
}
72+
73+
if a != 1 {
74+
t.Error(fmt.Sprintf("Expect: %d, Actual: %d ", 1, a))
75+
}
76+
77+
cache.Clear()
78+
err = cache.Remember("a", &a, 1*time.Minute, func() interface{} {
79+
return 3
80+
})
81+
82+
if err != nil {
83+
t.Error(err)
84+
}
85+
86+
if a != 3 {
87+
t.Error(fmt.Sprintf("Expect: %d, Actual: %d ", 3, a))
88+
}
89+
}
90+
91+
func TestMemoryCache(t *testing.T) {
92+
Register("memory", NewMemoryStore("thinkgo"))
93+
94+
cache, err := Cache("memory")
95+
96+
if err != nil {
97+
t.Error(err)
98+
}
99+
testCache(t, cache)
100+
}
101+
102+
func TestRedisCache(t *testing.T) {
103+
pool := &redis.Pool{
104+
MaxIdle: 5,
105+
MaxActive: 1000,
106+
IdleTimeout: 300 * time.Second,
107+
Wait: true,
108+
// Other pool configuration not shown in this example.
109+
Dial: func() (redis.Conn, error) {
110+
c, err := redis.Dial("tcp", "127.0.0.1:6379")
111+
if err != nil {
112+
return nil, err
113+
}
114+
return c, nil
115+
},
116+
}
117+
118+
cache, err := Cache(NewRedisStore(pool, "thinkgo"))
119+
if err != nil {
120+
t.Error(err)
121+
}
122+
testCache(t, cache)
123+
}

0 commit comments

Comments
 (0)