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, 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 {
|
||||
t.Errorf("cannot make bolt: %v", err)
|
||||
} else {
|
||||
|
|
@ -92,6 +104,12 @@ func TestImplementations(t *testing.T) {
|
|||
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"
|
||||
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