package cache import ( "context" "encoding/json" "fmt" "log" "os" "time" "github.com/go-redis/redis/v8" "sensor-server/internal/models" ) var RedisClient *redis.Client // InitRedis Redis 초기화 func InitRedis() error { RedisClient = redis.NewClient(&redis.Options{ Addr: fmt.Sprintf("%s:%s", getEnv("REDIS_HOST", "localhost"), getEnv("REDIS_PORT", "6379")), Password: getEnv("REDIS_PASSWORD", ""), DB: 0, }) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() _, err := RedisClient.Ping(ctx).Result() if err != nil { return fmt.Errorf("failed to connect to Redis: %v", err) } log.Println("Redis initialized successfully") return nil } // GetRedisClient Redis 클라이언트 반환 func GetRedisClient() *redis.Client { return RedisClient } // CacheLatestReading 최신 센서 데이터 캐시 func CacheLatestReading(deviceID string, reading *models.SensorReading) error { ctx := context.Background() key := fmt.Sprintf("latest:%s", deviceID) data, err := json.Marshal(reading) if err != nil { return err } // 1시간 동안 캐시 return RedisClient.Set(ctx, key, data, time.Hour).Err() } // GetLatestReading 캐시된 최신 센서 데이터 조회 func GetLatestReading(deviceID string) (*models.SensorReading, error) { ctx := context.Background() key := fmt.Sprintf("latest:%s", deviceID) data, err := RedisClient.Get(ctx, key).Result() if err != nil { return nil, err } var reading models.SensorReading err = json.Unmarshal([]byte(data), &reading) if err != nil { return nil, err } return &reading, nil } // CacheDeviceInfo 디바이스 정보 캐시 func CacheDeviceInfo(device *models.Device) error { ctx := context.Background() key := fmt.Sprintf("device:%s", device.DeviceID) data, err := json.Marshal(device) if err != nil { return err } // 24시간 동안 캐시 return RedisClient.Set(ctx, key, data, 24*time.Hour).Err() } // GetDeviceInfo 캐시된 디바이스 정보 조회 func GetDeviceInfo(deviceID string) (*models.Device, error) { ctx := context.Background() key := fmt.Sprintf("device:%s", deviceID) data, err := RedisClient.Get(ctx, key).Result() if err != nil { return nil, err } var device models.Device err = json.Unmarshal([]byte(data), &device) if err != nil { return nil, err } return &device, nil } // BroadcastSensorData WebSocket 브로드캐스트용 데이터 캐시 func BroadcastSensorData(reading *models.SensorReading) error { ctx := context.Background() key := "broadcast:sensor_data" data, err := json.Marshal(reading) if err != nil { return err } // Redis Pub/Sub을 통해 브로드캐스트 return RedisClient.Publish(ctx, key, data).Err() } // getEnv 환경변수 조회 (기본값 포함) func getEnv(key, defaultValue string) string { if value := os.Getenv(key); value != "" { return value } return defaultValue }