feat: add classification fields to episode service

This commit is contained in:
2026-07-06 20:46:48 +02:00
parent e75845b78a
commit 8b8f85bea7
2 changed files with 17 additions and 11 deletions

View File

@@ -4,6 +4,7 @@ package service
import ( import (
"context" "context"
"fmt" "fmt"
"sync"
"time" "time"
"mal/integrations/jikan" "mal/integrations/jikan"
@@ -23,13 +24,15 @@ type realClock struct{}
func (realClock) Now() time.Time { return time.Now() } func (realClock) Now() time.Time { return time.Now() }
type EpisodeService struct { type EpisodeService struct {
queries *db.Queries queries *db.Queries
jikan *jikan.Client jikan *jikan.Client
providers []domain.EpisodeAvailabilityProvider providers []domain.EpisodeAvailabilityProvider
titles domain.EpisodeTitleProvider titles domain.EpisodeTitleProvider
clock Clock clock Clock
enabled bool enabled bool
titleLoad singleflight.Group titleLoad singleflight.Group
classificationLoad singleflight.Group
cacheMu sync.Mutex
} }
func NewEpisodeService(queries *db.Queries, jikanClient *jikan.Client, providers []domain.EpisodeAvailabilityProvider, titles domain.EpisodeTitleProvider, enabled bool) domain.EpisodeService { func NewEpisodeService(queries *db.Queries, jikanClient *jikan.Client, providers []domain.EpisodeAvailabilityProvider, titles domain.EpisodeTitleProvider, enabled bool) domain.EpisodeService {

View File

@@ -50,6 +50,9 @@ func (s *EpisodeService) loadEpisodeTitles(ctx context.Context, anime domain.Ani
return domain.CanonicalEpisodeList{}, err return domain.CanonicalEpisodeList{}, err
} }
s.cacheMu.Lock()
defer s.cacheMu.Unlock()
payload, row, ok := s.cachedEpisodePayload(ctx, anime) payload, row, ok := s.cachedEpisodePayload(ctx, anime)
if !ok { if !ok {
return domain.CanonicalEpisodeList{}, errors.New("episode titles: episode availability cache disappeared") return domain.CanonicalEpisodeList{}, errors.New("episode titles: episode availability cache disappeared")
@@ -59,7 +62,7 @@ func (s *EpisodeService) loadEpisodeTitles(ctx context.Context, anime domain.Ani
if !changed { if !changed {
return payload, nil return payload, nil
} }
if err := s.storeEnrichedTitles(ctx, row, payload); err != nil { if err := s.storeEnrichedPayload(ctx, row, payload); err != nil {
return domain.CanonicalEpisodeList{}, err return domain.CanonicalEpisodeList{}, err
} }
@@ -88,10 +91,10 @@ func (s *EpisodeService) cachedEpisodePayload(ctx context.Context, anime domain.
return enrichCachedPayload(payload, row), row, true return enrichCachedPayload(payload, row), row, true
} }
func (s *EpisodeService) storeEnrichedTitles(ctx context.Context, row db.EpisodeAvailabilityCache, payload domain.CanonicalEpisodeList) error { func (s *EpisodeService) storeEnrichedPayload(ctx context.Context, row db.EpisodeAvailabilityCache, payload domain.CanonicalEpisodeList) error {
body, err := json.Marshal(payload) body, err := json.Marshal(payload)
if err != nil { if err != nil {
return fmt.Errorf("episode titles: encode cache: %w", err) return fmt.Errorf("episode metadata: encode cache: %w", err)
} }
err = s.queries.UpsertEpisodeAvailabilityCache(ctx, db.UpsertEpisodeAvailabilityCacheParams{ err = s.queries.UpsertEpisodeAvailabilityCache(ctx, db.UpsertEpisodeAvailabilityCacheParams{
AnimeID: row.AnimeID, AnimeID: row.AnimeID,
@@ -104,7 +107,7 @@ func (s *EpisodeService) storeEnrichedTitles(ctx context.Context, row db.Episode
LastError: row.LastError, LastError: row.LastError,
}) })
if err != nil { if err != nil {
return fmt.Errorf("episode titles: update cache: %w", err) return fmt.Errorf("episode metadata: update cache: %w", err)
} }
return nil return nil
} }