ForFarm/backend/internal/services/weather/cached_fetcher.go

53 lines
1.3 KiB
Go

package weather
import (
"context"
"fmt"
"time"
"log/slog"
"github.com/forfarm/backend/internal/domain"
"github.com/patrickmn/go-cache"
)
type CachedWeatherFetcher struct {
next domain.WeatherFetcher
cache *cache.Cache
logger *slog.Logger
}
func NewCachedWeatherFetcher(fetcher domain.WeatherFetcher, ttl time.Duration, cleanupInterval time.Duration, logger *slog.Logger) domain.WeatherFetcher {
c := cache.New(ttl, cleanupInterval)
return &CachedWeatherFetcher{
next: fetcher,
cache: c,
logger: logger,
}
}
func (f *CachedWeatherFetcher) GetCurrentWeatherByCoords(ctx context.Context, lat, lon float64) (*domain.WeatherData, error) {
cacheKey := fmt.Sprintf("weather_coords_%.4f_%.4f", lat, lon)
if data, found := f.cache.Get(cacheKey); found {
if weatherData, ok := data.(*domain.WeatherData); ok {
return weatherData, nil
}
f.logger.Warn("Invalid data type found in weather cache", "key", cacheKey)
}
f.logger.Debug("Cache miss for weather data", "key", cacheKey)
weatherData, err := f.next.GetCurrentWeatherByCoords(ctx, lat, lon)
if err != nil {
return nil, err
}
if weatherData != nil {
f.cache.Set(cacheKey, weatherData, cache.DefaultExpiration) // Uses the TTL set during cache creation
f.logger.Debug("Stored fetched weather data in cache", "key", cacheKey)
}
return weatherData, nil
}