diff --git a/cache/cache.go b/cache/cache.go index 4ec14ba8..79922926 100644 --- a/cache/cache.go +++ b/cache/cache.go @@ -1,6 +1,7 @@ // Package cache is a caching interface package cache +// Cache is an interface for caching type Cache interface { // Initialise options Init(...Option) error @@ -14,6 +15,15 @@ type Cache interface { String() string } -type Options struct{} +type Options struct { + Nodes []string +} type Option func(o *Options) + +// Nodes sets the nodes for the cache +func Nodes(v ...string) Option { + return func(o *Options) { + o.Nodes = v + } +} diff --git a/cache/memcache/memcache.go b/cache/memcache/memcache.go new file mode 100644 index 00000000..c94aab41 --- /dev/null +++ b/cache/memcache/memcache.go @@ -0,0 +1,80 @@ +// Package memcache is a memcache implementation of the Cache +package memcache + +import ( + "encoding/json" + + "github.com/bradfitz/gomemcache/memcache" + "github.com/micro/go-micro/v2/cache" +) + +type memcacheCache struct { + options cache.Options + client *memcache.Client +} + +type memcacheItem struct { + Key string + Value interface{} +} + +func (m *memcacheCache) Init(opts ...cache.Option) error { + for _, o := range opts { + o(&m.options) + } + return nil +} + +func (m *memcacheCache) Get(key string) (interface{}, error) { + item, err := m.client.Get(key) + if err != nil { + return nil, err + } + + var mc *memcacheItem + + if err := json.Unmarshal(item.Value, &mc); err != nil { + return nil, err + } + + return mc.Value, nil +} + +func (m *memcacheCache) Set(key string, val interface{}) error { + b, err := json.Marshal(val) + if err != nil { + return err + } + + return m.client.Set(&memcache.Item{ + Key: key, + Value: b, + }) +} + +func (m *memcacheCache) Delete(key string) error { + return m.client.Delete(key) +} + +func (m *memcacheCache) String() string { + return "memcache" +} + +// NewCache returns a new memcache Cache +func NewCache(opts ...cache.Option) cache.Cache { + var options cache.Options + for _, o := range opts { + o(&options) + } + + // get and set the nodes + nodes := options.Nodes + if len(nodes) == 0 { + nodes = []string{"localhost:11211"} + } + + return &memcacheCache{ + options: options, + client: memcache.New(nodes...), + } +} diff --git a/go.mod b/go.mod index 1be89774..b34c2ef8 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/BurntSushi/toml v0.3.1 github.com/bitly/go-simplejson v0.5.0 github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect + github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b github.com/bwmarrin/discordgo v0.20.2 github.com/caddyserver/certmagic v0.10.6 github.com/coreos/bbolt v1.3.3 // indirect diff --git a/go.sum b/go.sum index 0b9faa51..ff5f0016 100644 --- a/go.sum +++ b/go.sum @@ -62,6 +62,8 @@ github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngE github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= +github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b h1:L/QXpzIa3pOvUGt1D1lA5KjYhPBAN/3iWdP7xeFS9F0= +github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA= github.com/bwmarrin/discordgo v0.20.2 h1:nA7jiTtqUA9lT93WL2jPjUp8ZTEInRujBdx1C9gkr20= github.com/bwmarrin/discordgo v0.20.2/go.mod h1:O9S4p+ofTFwB02em7jkpkV8M3R0/PUVOwN61zSZ0r4Q= github.com/caddyserver/certmagic v0.10.6 h1:sCya6FmfaN74oZE46kqfaFOVoROD/mF36rTQfjN7TZc=