memcache a go
parent
ee88d4bbfd
commit
67478aae8e
|
|
@ -0,0 +1,49 @@
|
||||||
|
package storage
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
cache "github.com/patrickmn/go-cache"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Cache struct {
|
||||||
|
db *cache.Cache
|
||||||
|
path string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCache(path ...string) (*Cache, error) {
|
||||||
|
var err error = nil
|
||||||
|
c := &Cache{db: cache.New(0, time.Minute*15), path: ""}
|
||||||
|
if len(path) != 0 {
|
||||||
|
c.path = path[0]
|
||||||
|
if _, err := os.Stat(c.path); err == nil {
|
||||||
|
err = c.db.LoadFile(c.path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return c, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Cache) Get(key string) ([]byte, error) {
|
||||||
|
v, ok := c.db.Get(key)
|
||||||
|
if !ok {
|
||||||
|
return nil, ErrNotFound
|
||||||
|
}
|
||||||
|
b, ok := v.([]byte)
|
||||||
|
if !ok {
|
||||||
|
return nil, ErrNotImpl
|
||||||
|
}
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Cache) Set(key string, value []byte) error {
|
||||||
|
c.db.Set(key, value, 0)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Cache) Close() error {
|
||||||
|
if c.path != "" {
|
||||||
|
return c.db.SaveFile(c.path)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
18
db_test.go
18
db_test.go
|
|
@ -42,6 +42,18 @@ func TestImplementations(t *testing.T) {
|
||||||
cases = append(cases, &mock{m: make(map[string][]byte)})
|
cases = append(cases, &mock{m: make(map[string][]byte)})
|
||||||
cases = append(cases, NewMap())
|
cases = append(cases, NewMap())
|
||||||
|
|
||||||
|
if cacheMem, err := NewCache(); err != nil {
|
||||||
|
t.Errorf("cannot make cache/mem: %v", err)
|
||||||
|
} else {
|
||||||
|
cases = append(cases, cacheMem)
|
||||||
|
}
|
||||||
|
|
||||||
|
if cacheFile, err := NewCache(path.Join(dir, "cache")); err != nil {
|
||||||
|
t.Errorf("cannot make cache/file: %v", err)
|
||||||
|
} else {
|
||||||
|
cases = append(cases, cacheFile)
|
||||||
|
}
|
||||||
|
|
||||||
if bolt, err := NewBolt(path.Join(dir, "bolt")); err != nil {
|
if bolt, err := NewBolt(path.Join(dir, "bolt")); err != nil {
|
||||||
t.Errorf("cannot make bolt: %v", err)
|
t.Errorf("cannot make bolt: %v", err)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -92,6 +104,12 @@ func TestImplementations(t *testing.T) {
|
||||||
t.Errorf("cannot make mongo: %v", err)
|
t.Errorf("cannot make mongo: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if memcache, err := NewMemcache("localhost:11211"); err != nil {
|
||||||
|
t.Errorf("cannot make memcache: %v", err)
|
||||||
|
} else {
|
||||||
|
cases = append(cases, memcache)
|
||||||
|
}
|
||||||
|
|
||||||
validKey := "key"
|
validKey := "key"
|
||||||
validValue := []byte("value")
|
validValue := []byte("value")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,80 @@
|
||||||
|
package storage
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
|
||||||
|
"github.com/bradfitz/gomemcache/memcache"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Memcache struct {
|
||||||
|
db *memcache.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
type serverSelector struct {
|
||||||
|
addrs []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ss *serverSelector) PickServer(key string) (net.Addr, error) {
|
||||||
|
return &netAddr{
|
||||||
|
network: "tcp",
|
||||||
|
addr: ss.addrs[0],
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ss *serverSelector) Each(each func(net.Addr) error) error {
|
||||||
|
for _, addr := range ss.addrs {
|
||||||
|
if err := each(&netAddr{
|
||||||
|
network: "tcp",
|
||||||
|
addr: addr,
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type netAddr struct {
|
||||||
|
network string
|
||||||
|
addr string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *netAddr) Network() string {
|
||||||
|
return a.network
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *netAddr) String() string {
|
||||||
|
return a.addr
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMemcache(addr string, addrs ...string) (*Memcache, error) {
|
||||||
|
ss := &serverSelector{
|
||||||
|
addrs: append(addrs, addr),
|
||||||
|
}
|
||||||
|
if err := ss.Each(func(addr net.Addr) error {
|
||||||
|
conn, err := net.Dial("tcp", addr.String())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return conn.Close()
|
||||||
|
}); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
db := memcache.NewFromSelector(ss)
|
||||||
|
return &Memcache{db: db}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mc *Memcache) Get(key string) ([]byte, error) {
|
||||||
|
v, err := mc.db.Get(key)
|
||||||
|
return v.Value, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mc *Memcache) Set(key string, value []byte) error {
|
||||||
|
return mc.db.Set(&memcache.Item{
|
||||||
|
Key: key,
|
||||||
|
Value: value,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mc *Memcache) Close() error {
|
||||||
|
return mc.db.FlushAll()
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue