Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion .travis.yml
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
49 changes: 49 additions & 0 deletions cache/README.md
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`.
38 changes: 38 additions & 0 deletions cache/cache.go
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
}
123 changes: 123 additions & 0 deletions cache/cache_test.go
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)
}
Loading