Files
old-svijetlastrana/infra/cache/cache.go
2018-04-25 13:16:36 +02:00

145 lines
3.1 KiB
Go

package cache
import (
"encoding/json"
"fmt"
redis "gopkg.in/redis.v5"
"time"
"sync"
"bitbucket.org/nemt/nemt-portal-api/domain"
"bitbucket.org/nemt/nemt-portal-api/domain/contract"
"bitbucket.org/nemt/nemt-portal-api/infra/config"
"bitbucket.org/nemt/nemt-portal-api/infra/errors"
)
var (
instance *RedisCache
once sync.Once
)
// RedisCache implements the CacheManager interface
type RedisCache struct {
cfg *config.Config
redis *redis.Client
}
// Instance returns a CacheManager instance
func Instance(cfg *config.Config) contract.CacheManager {
once.Do(func() {
client := redis.NewFailoverClient(&redis.FailoverOptions{
MasterName: "master01",
SentinelAddrs: []string{fmt.Sprintf("%s:%v", cfg.Cache.Server, cfg.Cache.Port)},
Password: cfg.Cache.Pass,
DB: cfg.Cache.DB,
})
instance = &RedisCache{cfg, client}
})
return instance
}
func (r *RedisCache) buildKey(key string) string {
return fmt.Sprintf("%s-%s", r.cfg.Cache.Prefix, key)
}
// GetItem returns an Item from cache
func (r *RedisCache) GetItem(key string) (data []byte, err error) {
val, err := r.redis.Get(r.buildKey(key)).Bytes()
if err == redis.Nil {
return val, domain.ErrCacheMiss
} else if err != nil {
return val, errors.Wrap(err)
}
return val, nil
}
// SetItem sets an item in cache
func (r *RedisCache) SetItem(key string, data []byte) error {
err := r.redis.Set(r.buildKey(key), data, r.cfg.Cache.DefaultExpiration).Err()
if err != nil {
return errors.Wrap(err)
}
return nil
}
// GetString returns an string from cache
func (r *RedisCache) GetString(key string) (data string, err error) {
val, err := r.GetItem(key)
if err == domain.ErrCacheMiss {
return data, domain.ErrCacheMiss
} else if err != nil {
return data, errors.Wrap(err)
}
return string(val), nil
}
// SetString sets an item in cache
func (r *RedisCache) SetString(key string, data string) error {
err := r.SetItem(key, []byte(data))
if err != nil {
return errors.Wrap(err)
}
return nil
}
// GetStruct returns an struct from cache
func (r *RedisCache) GetStruct(key string, data interface{}) (err error) {
val, err := r.GetItem(key)
if err == domain.ErrCacheMiss {
return domain.ErrCacheMiss
} else if err != nil {
return errors.Wrap(err)
}
err = json.Unmarshal(val, &data)
if err != nil {
return errors.Wrap(err)
}
return nil
}
// SetStruct sets an item in cache
func (r *RedisCache) SetStruct(key string, data interface{}) error {
dataString, err := json.Marshal(data)
if err != nil {
return errors.Wrap(err)
}
err = r.SetItem(key, dataString)
if err != nil {
return errors.Wrap(err)
}
return nil
}
// GetExpiration returns the expiration time for a key
func (r *RedisCache) GetExpiration(key string) (expiration time.Duration, err error) {
expiration, err = r.redis.TTL(r.buildKey(key)).Result()
if err != nil {
return expiration, errors.Wrap(err)
}
return expiration, nil
}
// SetExpiration sets the expiration time for a key
func (r *RedisCache) SetExpiration(key string, expiration time.Duration) (err error) {
err = r.redis.Expire(r.buildKey(key), expiration).Err()
if err != nil {
return errors.Wrap(err)
}
return nil
}