-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4 from thinkoner/develop
Added cache
- Loading branch information
Showing
11 changed files
with
996 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,21 @@ | ||
language: go | ||
|
||
sudo: false | ||
|
||
go: | ||
- "1.x" | ||
- 1.6.x | ||
- 1.7.x | ||
- 1.8.x | ||
- 1.9.x | ||
- 1.10.x | ||
- 1.11.x | ||
- master | ||
|
||
services: | ||
- redis-server | ||
|
||
before_install: | ||
- go get github.com/mattn/goveralls | ||
|
||
script: | ||
- $HOME/gopath/bin/goveralls -service=travis-ci |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# ThinkGo-Cache | ||
|
||
`ThinkGo-Cache` is a cache library for Golang,it currently supports redis, memory, and can customize the store adapter. | ||
|
||
## Installation | ||
|
||
``` | ||
go get github.com/thinkoner/thinkgo/cache | ||
``` | ||
|
||
## Usage | ||
|
||
#### Basic Usage | ||
|
||
```go | ||
import ( | ||
"github.com/thinkoner/thinkgo/cache" | ||
"time" | ||
) | ||
|
||
|
||
var foo string | ||
|
||
// Create a cache with memory store | ||
c, _ := cache.Cache(cache.NewMemoryStore("thinkgo")) | ||
|
||
// Set the value | ||
c.Put("foo", "thinkgo", 10 * time.Minute) | ||
|
||
// Get the string associated with the key "foo" from the cache | ||
c.Get("foo", &foo) | ||
|
||
``` | ||
|
||
#### Retrieve & Store | ||
|
||
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: | ||
|
||
```go | ||
var foo int | ||
|
||
cache.Remember("foo", &a, 1*time.Minute, func() interface{} { | ||
return "thinkgo" | ||
}) | ||
``` | ||
|
||
## License | ||
|
||
This project is licensed under the `Apache 2.0 license`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package cache | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
) | ||
|
||
var adapters = make(map[string]Store) | ||
|
||
// Register Register a cache adapter available by the adapter name. | ||
func Register(name string, adapter Store) error { | ||
if adapter == nil { | ||
return errors.New("cache: Register adapter is nil") | ||
} | ||
if _, ok := adapters[name]; ok { | ||
return errors.New("cache: Register called twice for adapter " + name) | ||
} | ||
adapters[name] = adapter | ||
return nil | ||
} | ||
|
||
// NewCache Create a new cache by adapter name. | ||
func Cache(adapter interface{}) (*Repository, error) { | ||
var store Store | ||
switch adapter.(type) { | ||
case string: | ||
var ok bool | ||
store, ok = adapters[adapter.(string)] | ||
if !ok { | ||
err := fmt.Errorf("cache: unknown adapter name %q (forgot to import?)", adapter.(string)) | ||
return nil, err | ||
} | ||
case Store: | ||
store = adapter.(Store) | ||
} | ||
|
||
return NewRepository(store), nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
package cache | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
"time" | ||
|
||
"github.com/gomodule/redigo/redis" | ||
) | ||
|
||
func testCache(t *testing.T, cache *Repository) { | ||
var a int | ||
var b string | ||
err := cache.Get("a", &a) | ||
if err == nil { | ||
t.Error("Getting A found value that shouldn't exist:", a) | ||
} | ||
|
||
err = cache.Get("b", &b) | ||
if err == nil { | ||
t.Error("Getting B found value that shouldn't exist:", b) | ||
} | ||
|
||
cache.Put("a", 1, 10*time.Minute) | ||
cache.Put("b", "thinkgo", 10*time.Minute) | ||
|
||
err = cache.Get("a", &a) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
|
||
if a != 1 { | ||
t.Error("Expect: ", 1) | ||
} | ||
|
||
err = cache.Get("b", &b) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
|
||
if b != "thinkgo" { | ||
t.Error("Expect: ", "thinkgo") | ||
} | ||
|
||
testCacheRemember(t, cache) | ||
} | ||
|
||
func testCacheRemember(t *testing.T, cache *Repository) { | ||
cache.Clear() | ||
|
||
var a int | ||
|
||
err := cache.Remember("a", &a, 1*time.Minute, func() interface{} { | ||
return 1 | ||
}) | ||
|
||
if err != nil { | ||
t.Error(err) | ||
} | ||
|
||
if a != 1 { | ||
t.Error(fmt.Sprintf("Expect: %d, Actual: %d ", 1, a)) | ||
} | ||
|
||
err = cache.Remember("a", &a, 1*time.Minute, func() interface{} { | ||
return 2 | ||
}) | ||
|
||
if err != nil { | ||
t.Error(err) | ||
} | ||
|
||
if a != 1 { | ||
t.Error(fmt.Sprintf("Expect: %d, Actual: %d ", 1, a)) | ||
} | ||
|
||
cache.Clear() | ||
err = cache.Remember("a", &a, 1*time.Minute, func() interface{} { | ||
return 3 | ||
}) | ||
|
||
if err != nil { | ||
t.Error(err) | ||
} | ||
|
||
if a != 3 { | ||
t.Error(fmt.Sprintf("Expect: %d, Actual: %d ", 3, a)) | ||
} | ||
} | ||
|
||
func TestMemoryCache(t *testing.T) { | ||
Register("memory", NewMemoryStore("thinkgo")) | ||
|
||
cache, err := Cache("memory") | ||
|
||
if err != nil { | ||
t.Error(err) | ||
} | ||
testCache(t, cache) | ||
} | ||
|
||
func TestRedisCache(t *testing.T) { | ||
pool := &redis.Pool{ | ||
MaxIdle: 5, | ||
MaxActive: 1000, | ||
IdleTimeout: 300 * time.Second, | ||
Wait: true, | ||
// Other pool configuration not shown in this example. | ||
Dial: func() (redis.Conn, error) { | ||
c, err := redis.Dial("tcp", "127.0.0.1:6379") | ||
if err != nil { | ||
return nil, err | ||
} | ||
return c, nil | ||
}, | ||
} | ||
|
||
cache, err := Cache(NewRedisStore(pool, "thinkgo")) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
testCache(t, cache) | ||
} |
Oops, something went wrong.