update ignore
This commit is contained in:
No files matched your search
+133
@@ -0,0 +1,133 @@
|
||||
// File: /home/meninjar/goprint/service-general/internal/infrastructure/cache/redis.go
|
||||
package cache
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
)
|
||||
|
||||
// RedisCache implements Cache interface using Redis
|
||||
type RedisCache struct {
|
||||
client *redis.Client
|
||||
config CacheConfig
|
||||
}
|
||||
|
||||
// NewRedisCache creates a new Redis cache instance
|
||||
func NewRedisCache(config CacheConfig) (Cache, error) {
|
||||
if !config.Enabled {
|
||||
return &NoOpCache{}, nil
|
||||
}
|
||||
|
||||
client := redis.NewClient(&redis.Options{
|
||||
Addr: fmt.Sprintf("%s:%d", config.Redis.Host, config.Redis.Port),
|
||||
Password: config.Redis.Password,
|
||||
DB: config.Redis.DB,
|
||||
})
|
||||
|
||||
// Test connection
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
if err := client.Ping(ctx).Err(); err != nil {
|
||||
return nil, fmt.Errorf("failed to connect to Redis: %w", err)
|
||||
}
|
||||
|
||||
return &RedisCache{
|
||||
client: client,
|
||||
config: config,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Get retrieves a value from cache
|
||||
func (r *RedisCache) Get(ctx context.Context, key string) (string, error) {
|
||||
return r.client.Get(ctx, key).Result()
|
||||
}
|
||||
|
||||
// Set stores a value in cache
|
||||
func (r *RedisCache) Set(ctx context.Context, key string, value string, expiration time.Duration) error {
|
||||
return r.client.Set(ctx, key, value, expiration).Err()
|
||||
}
|
||||
|
||||
// Delete removes a value from cache
|
||||
func (r *RedisCache) Delete(ctx context.Context, key string) error {
|
||||
return r.client.Del(ctx, key).Err()
|
||||
}
|
||||
|
||||
// Exists checks if a key exists in cache
|
||||
func (r *RedisCache) Exists(ctx context.Context, key string) (bool, error) {
|
||||
result, err := r.client.Exists(ctx, key).Result()
|
||||
return result > 0, err
|
||||
}
|
||||
|
||||
// GetStruct retrieves and unmarshals a struct from cache
|
||||
func (r *RedisCache) GetStruct(ctx context.Context, key string, dest interface{}) error {
|
||||
data, err := r.client.Get(ctx, key).Result()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return json.Unmarshal([]byte(data), dest)
|
||||
}
|
||||
|
||||
// SetStruct marshals and stores a struct in cache
|
||||
func (r *RedisCache) SetStruct(ctx context.Context, key string, value interface{}, expiration time.Duration) error {
|
||||
data, err := json.Marshal(value)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal value: %w", err)
|
||||
}
|
||||
return r.client.Set(ctx, key, data, expiration).Err()
|
||||
}
|
||||
|
||||
// Increment increments a numeric value in cache
|
||||
func (r *RedisCache) Increment(ctx context.Context, key string, delta int64) (int64, error) {
|
||||
return r.client.IncrBy(ctx, key, delta).Result()
|
||||
}
|
||||
|
||||
// Decrement decrements a numeric value in cache
|
||||
func (r *RedisCache) Decrement(ctx context.Context, key string, delta int64) (int64, error) {
|
||||
return r.client.DecrBy(ctx, key, delta).Result()
|
||||
}
|
||||
|
||||
// TTL returns the time to live for a key
|
||||
func (r *RedisCache) TTL(ctx context.Context, key string) (time.Duration, error) {
|
||||
return r.client.TTL(ctx, key).Result()
|
||||
}
|
||||
|
||||
// GetRedisClient mendapatkan Redis client
|
||||
func (r *RedisCache) GetRedisClient() interface{} {
|
||||
return r.client
|
||||
}
|
||||
|
||||
// Close closes the Redis connection
|
||||
func (r *RedisCache) Close() error {
|
||||
return r.client.Close()
|
||||
}
|
||||
|
||||
// Health checks the health of the cache
|
||||
func (r *RedisCache) Health(ctx context.Context) error {
|
||||
return r.client.Ping(ctx).Err()
|
||||
}
|
||||
|
||||
// MGet retrieves multiple values from cache
|
||||
func (r *RedisCache) MGet(ctx context.Context, keys ...string) ([]interface{}, error) {
|
||||
return r.client.MGet(ctx, keys...).Result()
|
||||
}
|
||||
|
||||
// MSet stores multiple values in cache
|
||||
func (r *RedisCache) MSet(ctx context.Context, items map[string]interface{}, expiration time.Duration) error {
|
||||
pipe := r.client.Pipeline()
|
||||
|
||||
for key, value := range items {
|
||||
data, err := json.Marshal(value)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal value for key %s: %w", key, err)
|
||||
}
|
||||
pipe.Set(ctx, key, data, expiration)
|
||||
}
|
||||
|
||||
_, err := pipe.Exec(ctx)
|
||||
return err
|
||||
}
|
||||
Reference in New Issue
Block a user