You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
108 lines
1.6 KiB
108 lines
1.6 KiB
package cache |
|
|
|
import ( |
|
"errors" |
|
"github.com/vmihailenco/msgpack/v4" |
|
"net/url" |
|
"strconv" |
|
"strings" |
|
"time" |
|
) |
|
|
|
const ( |
|
Memcache = "memcache" |
|
Redis = "redis" |
|
Memory = "memory" |
|
) |
|
|
|
var ( |
|
ErrInvalidDriver = errors.New("invalid driver") |
|
) |
|
|
|
type CacheInterface interface { |
|
Has(key string) bool |
|
Get(key string, dst ...interface{}) ([]byte, error) |
|
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: |
|
return NewRedisCache(RedisSettings{ |
|
Address: u.Host, |
|
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) |
|
} |
|
|
|
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 |
|
}
|
|
|