cacheinterface/cache.go

116 lines
1.7 KiB
Go
Raw Normal View History

2019-10-02 04:10:27 +00:00
package cache
import (
"errors"
"github.com/vmihailenco/msgpack/v4"
"net"
2019-10-02 04:10:27 +00:00
"net/url"
"strconv"
2019-10-02 04:10:27 +00:00
"strings"
"time"
)
const (
Memcache = "memcache"
Redis = "redis"
Memory = "memory"
2019-10-02 04:10:27 +00:00
)
var (
ErrInvalidDriver = errors.New("invalid driver")
)
type CacheInterface interface {
Has(key string) bool
Get(key string, dst ...interface{}) ([]byte, error)
2019-10-02 04:10:27 +00:00
Set(key string, val interface{}, ttl time.Duration) (err error)
Del(key string) error
}
func New(uri string) (CacheInterface, error) {
u, err := url.Parse(uri)
if err != nil {
return nil, err
}
query := u.Query()
switch u.Scheme {
case Redis:
port := u.Port()
if port == "" {
port = "6379"
}
2019-10-02 04:10:27 +00:00
return NewRedisCache(RedisSettings{
Address: net.JoinHostPort(u.Hostname(), port),
2019-10-02 04:10:27 +00:00
Password: query.Get("password"),
})
case Memcache:
return NewMemcacheCache(MemcacheSettings{
Servers: strings.Split(u.Host, ","),
})
case Memory:
cleanupTime := query.Get("cleanupTime")
if cleanupTime == "" {
cleanupTime = "30"
}
i, err := strconv.Atoi(cleanupTime)
if err != nil {
return nil, err
}
return NewMemoryCache(time.Duration(i) * time.Second)
2019-10-02 04:10:27 +00:00
}
return nil, ErrInvalidDriver
}
func encodeValue(val interface{}) ([]byte, error) {
var v []byte
if b, ok := val.([]byte); ok {
v = b
} else if s, ok := val.(string); ok {
b = []byte(s)
} else {
b, err := msgpack.Marshal(val)
if err != nil {
return nil, err
}
v = b
}
return v, nil
}
func decodeDst(b []byte, v interface{}) ([]byte, error) {
switch v := v.(type) {
case *[]byte:
if v != nil {
*v = b
return b, nil
}
case *string:
if v != nil {
*v = string(b)
return b, nil
}
}
err := msgpack.Unmarshal(b, v)
if err != nil {
return nil, err
}
return b, nil
}