171 lines
5.1 KiB
Go
171 lines
5.1 KiB
Go
package esi
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"time"
|
|
|
|
"go-eve-pi/options"
|
|
"go-eve-pi/types"
|
|
|
|
logger "git.site.quack-lab.dev/dave/cylogger"
|
|
)
|
|
|
|
type CacheDB interface {
|
|
GetCacheEntry(hash string) (*types.CacheEntry, error)
|
|
SaveCacheEntry(entry *types.CacheEntry) error
|
|
}
|
|
|
|
// CachedESI implements ESIInterface with caching
|
|
type CachedESI struct {
|
|
direct ESIInterface
|
|
db CacheDB
|
|
cacheValidity time.Duration
|
|
}
|
|
|
|
// NewCachedESI creates a new CachedESI instance
|
|
func NewCachedESI(direct ESIInterface, db CacheDB) *CachedESI {
|
|
// Parse cache validity ONCE at initialization
|
|
cacheValidity, err := time.ParseDuration(options.GlobalOptions.CacheValidity)
|
|
if err != nil {
|
|
logger.Error("Invalid cache validity duration %s: %v", options.GlobalOptions.CacheValidity, err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
logger.Info("Initializing CachedESI with cache validity: %v", cacheValidity)
|
|
return &CachedESI{
|
|
direct: direct,
|
|
db: db,
|
|
cacheValidity: cacheValidity,
|
|
}
|
|
}
|
|
|
|
// GetPlanetPI retrieves detailed information about a specific planet with caching
|
|
func (c *CachedESI) GetPlanetPI(ctx context.Context, characterID int, planetID int64, accessToken string) (*PlanetPI, error) {
|
|
funclog := logger.Default.WithPrefix("CachedESI.GetPlanetPI").WithPrefix(fmt.Sprintf("characterID=%d", characterID)).WithPrefix(fmt.Sprintf("planetID=%d", planetID))
|
|
funclog.Info("Starting")
|
|
|
|
hash := fmt.Sprintf("GetPlanetPI-%d-%d", characterID, planetID)
|
|
cached, err := c.db.GetCacheEntry(hash)
|
|
if err != nil {
|
|
funclog.Warning("Failed to get cache entry: %v", err)
|
|
}
|
|
if cached != nil {
|
|
funclog.Info("Cache hit for GetPlanetPI-%d-%d", characterID, planetID)
|
|
var planetPI PlanetPI
|
|
if err := json.Unmarshal([]byte(cached.Data), &planetPI); err != nil {
|
|
funclog.Error("Failed to unmarshal cached data: %v", err)
|
|
return nil, err
|
|
}
|
|
return &planetPI, nil
|
|
}
|
|
funclog.Info("Cache miss for GetPlanetPI-%d-%d", characterID, planetID)
|
|
|
|
apiresp, err := c.direct.GetPlanetPI(ctx, characterID, planetID, accessToken)
|
|
if err != nil {
|
|
funclog.Error("Failed to get planet PI: %v", err)
|
|
return nil, err
|
|
}
|
|
apirespjson, err := json.Marshal(apiresp)
|
|
if err != nil {
|
|
funclog.Error("Failed to marshal planet PI: %v", err)
|
|
return nil, err
|
|
}
|
|
cacheEntry := &types.CacheEntry{
|
|
Hash: hash,
|
|
Data: string(apirespjson),
|
|
CachedAt: time.Now(),
|
|
}
|
|
err = c.db.SaveCacheEntry(cacheEntry)
|
|
if err != nil {
|
|
funclog.Warning("Failed to save cache entry: %v", err)
|
|
}
|
|
return apiresp, nil
|
|
}
|
|
|
|
// GetPlanetName retrieves planet name with caching
|
|
func (c *CachedESI) GetPlanetName(ctx context.Context, planetID int64) (*PlanetName, error) {
|
|
funclog := logger.Default.WithPrefix("CachedESI.GetPlanetName").WithPrefix(fmt.Sprintf("planetID=%d", planetID))
|
|
funclog.Info("Starting")
|
|
|
|
hash := fmt.Sprintf("GetPlanetName-%d", planetID)
|
|
cached, err := c.db.GetCacheEntry(hash)
|
|
if err != nil {
|
|
funclog.Warning("Failed to get cache entry: %v", err)
|
|
}
|
|
if cached != nil {
|
|
funclog.Info("Cache hit for GetPlanetName-%d", planetID)
|
|
var planetPI PlanetName
|
|
if err := json.Unmarshal([]byte(cached.Data), &planetPI); err != nil {
|
|
funclog.Error("Failed to unmarshal cached data: %v", err)
|
|
return nil, err
|
|
}
|
|
return &planetPI, nil
|
|
}
|
|
funclog.Info("Cache miss for GetPlanetName-%d", planetID)
|
|
apiresp, err := c.direct.GetPlanetName(ctx, planetID)
|
|
if err != nil {
|
|
funclog.Error("Failed to get planet name: %v", err)
|
|
return nil, err
|
|
}
|
|
apirespjson, err := json.Marshal(apiresp)
|
|
if err != nil {
|
|
funclog.Error("Failed to marshal planet name: %v", err)
|
|
return nil, err
|
|
}
|
|
cacheEntry := &types.CacheEntry{
|
|
Hash: hash,
|
|
Data: string(apirespjson),
|
|
CachedAt: time.Now(),
|
|
}
|
|
err = c.db.SaveCacheEntry(cacheEntry)
|
|
if err != nil {
|
|
funclog.Warning("Failed to save cache entry: %v", err)
|
|
}
|
|
return apiresp, nil
|
|
}
|
|
|
|
func (c *CachedESI) GetCharacterPlanets(ctx context.Context, characterID int, accessToken string) ([]Planet, error) {
|
|
funclog := logger.Default.WithPrefix("CachedESI.GetCharacterPlanets").WithPrefix(fmt.Sprintf("characterID=%d", characterID))
|
|
funclog.Info("Starting")
|
|
|
|
hash := fmt.Sprintf("GetCharacterPlanets-%d", characterID)
|
|
cached, err := c.db.GetCacheEntry(hash)
|
|
if err != nil {
|
|
funclog.Warning("Failed to get cache entry: %v", err)
|
|
}
|
|
if cached != nil {
|
|
funclog.Info("Cache hit for GetCharacterPlanets-%d", characterID)
|
|
var planets []Planet
|
|
if err := json.Unmarshal([]byte(cached.Data), &planets); err != nil {
|
|
funclog.Error("Failed to unmarshal cached data: %v", err)
|
|
return nil, err
|
|
}
|
|
return planets, nil
|
|
}
|
|
funclog.Info("Cache miss for GetCharacterPlanets-%d", characterID)
|
|
apiresp, err := c.direct.GetCharacterPlanets(ctx, characterID, accessToken)
|
|
if err != nil {
|
|
funclog.Error("Failed to get character planets: %v", err)
|
|
return nil, err
|
|
}
|
|
apirespjson, err := json.Marshal(apiresp)
|
|
if err != nil {
|
|
funclog.Error("Failed to marshal character planets: %v", err)
|
|
return nil, err
|
|
}
|
|
cacheEntry := &types.CacheEntry{
|
|
Hash: hash,
|
|
Data: string(apirespjson),
|
|
CachedAt: time.Now(),
|
|
}
|
|
err = c.db.SaveCacheEntry(cacheEntry)
|
|
if err != nil {
|
|
funclog.Warning("Failed to save cache entry: %v", err)
|
|
}
|
|
return apiresp, nil
|
|
}
|
|
|
|
var _ ESIInterface = &CachedESI{} |