memcache a go

master
Bel LaPointe 2019-03-14 09:26:26 -06:00
parent ee88d4bbfd
commit 67478aae8e
3 changed files with 147 additions and 0 deletions

49
cache.go Normal file
View File

@ -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
}

View File

@ -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")

80
memcached.go Normal file
View File

@ -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()
}