package cache import ( "context" "errors" "github.com/go-redis/redis/v8" "os" "time" ) func newRedisCache() Manager { redisClient := redis.NewClient(&redis.Options{ Addr: os.Getenv("REDIS_URL"), Username: os.Getenv("REDIS_USERNAME"), Password: os.Getenv("REDIS_PASSWORD"), }) return &redisCache{redisClient} } type redisCache struct { client *redis.Client } func (r *redisCache) Set(key, value string, expiration time.Duration) error { ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) defer cancel() return r.client.Set(ctx, key, value, expiration).Err() } func (r *redisCache) Get(key string) (string, error) { ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) defer cancel() cacheValue := r.client.Get(ctx, key) return cacheValue.Val(), cacheValue.Err() } func (r *redisCache) Remove(key string) { ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) defer cancel() r.client.Del(ctx, key) } func newInMemCache() Manager { return &inMemCache{make(map[string]inMemEntry)} } type inMemEntry struct { value string expiration time.Time } type inMemCache struct { entries map[string]inMemEntry } func (i *inMemCache) Set(key, value string, expiration time.Duration) error { i.entries[key] = inMemEntry{ value: value, expiration: time.Now().Add(expiration), } return nil } func (i *inMemCache) Get(key string) (string, error) { if val, exists := i.entries[key]; exists { if val.expiration.Before(time.Now()) { delete(i.entries, key) } else { return val.value, nil } } return "", errors.New("no value for given key") } func (i *inMemCache) Remove(key string) { delete(i.entries, key) }