1
0
Fork 0
mirror of https://github.com/alice-lg/birdwatcher.git synced 2025-03-09 00:00:05 +01:00

Integrate redis backend with the Cache interface

This commit is contained in:
Benedikt Rudolph 2019-02-28 16:14:13 +01:00
parent 420f94928e
commit 6a9a0ab17e
4 changed files with 41 additions and 14 deletions

View file

@ -66,6 +66,10 @@ func toCache(key string, val Parsed) bool {
/* Convenience method to retrieve entries from the cache.
* Abstracts over the specific caching implementations.
* If err returned by cache.Get(key) is set, the value from the cache is not
* used. There is either a fault e.g. missing entry or the ttl is expired.
* Handling of specific error conditions e.g. ttl expired but entry present is
* possible but currently not implemented.
*/
func fromCache(key string) (Parsed, bool) {
val, err := cache.Get(key)

View file

@ -2,12 +2,15 @@ package bird
import (
"encoding/json"
"github.com/go-redis/redis"
"errors"
"time"
"github.com/go-redis/redis"
)
type RedisCache struct {
client *redis.Client
client *redis.Client
keyPrefix string
}
func NewRedisCache(config CacheConfig) (*RedisCache, error) {
@ -31,6 +34,7 @@ func NewRedisCache(config CacheConfig) (*RedisCache, error) {
}
func (self *RedisCache) Get(key string) (Parsed, error) {
key = self.keyPrefix + key //"B" + IPVersion + "_" + key
data, err := self.client.Get(key).Result()
if err != nil {
return NilParse, err
@ -39,15 +43,34 @@ func (self *RedisCache) Get(key string) (Parsed, error) {
parsed := Parsed{}
err = json.Unmarshal([]byte(data), &parsed)
return parsed, err
}
func (self *RedisCache) Set(key string, parsed Parsed) error {
payload, err := json.Marshal(parsed)
if err != nil {
return err
ttl, correct := parsed["ttl"].(time.Time)
if !correct {
return NilParse, errors.New("Invalid TTL value for key" + key)
}
_, err = self.client.Set(key, payload, time.Minute*5).Result()
return err
if ttl.Before(time.Now()) {
return NilParse, err // TTL expired
} else {
return parsed, err // cache hit
}
}
func (self *RedisCache) Set(key string, parsed Parsed, ttl int) error {
switch {
case ttl == 0:
return nil // do not cache
case ttl > 0:
key = self.keyPrefix + key //TODO "B" + IPVersion + "_" + key
payload, err := json.Marshal(parsed)
if err != nil {
return err
}
_, err = self.client.Set(key, payload, time.Duration(ttl)*time.Minute).Result()
return err
default: // ttl negative - invalid
return errors.New("Negative TTL value for key" + key)
}
}

View file

@ -23,7 +23,7 @@ func Test_RedisCacheAccess(t *testing.T) {
}
t.Log("Setting redis cache...")
err = cache.Set("testkey", parsed)
err = cache.Set("testkey", parsed, 5)
if err != nil {
t.Error(err)
}
@ -80,7 +80,7 @@ func Test_RedisCacheRoutes(t *testing.T) {
return
}
err = cache.Set("routes_protocol_test", parsed)
err = cache.Set("routes_protocol_test", parsed, 5)
if err != nil {
t.Error(err)
}

View file

@ -173,7 +173,7 @@ func main() {
var cache bird.Cache
if conf.Cache.UseRedis {
bird.CacheRedis, err = bird.NewRedisCache(conf.Cache)
cache, err = bird.NewRedisCache(conf.Cache)
if err != nil {
log.Fatal("Could not initialize redis cache, falling back to MemoryCache:", err)
}