refactor: remove metrics from episode service

This commit is contained in:
2026-06-23 15:08:54 +02:00
committed by Milas Holsting
parent 0d53d5efdc
commit a014ad40a9
4 changed files with 9 additions and 26 deletions

View File

@@ -132,13 +132,12 @@ func (s *EpisodeService) markFailure(ctx context.Context, anime domain.Anime, ca
} }
func (s *EpisodeService) getCached(ctx context.Context, anime domain.Anime) (domain.CanonicalEpisodeList, bool) { func (s *EpisodeService) getCached(ctx context.Context, anime domain.Anime) (domain.CanonicalEpisodeList, bool) {
return s.getDecodedCached(ctx, anime, "episode_availability") return s.getDecodedCached(ctx, anime)
} }
func (s *EpisodeService) getFreshCached(ctx context.Context, anime domain.Anime) (domain.CanonicalEpisodeList, bool) { func (s *EpisodeService) getFreshCached(ctx context.Context, anime domain.Anime) (domain.CanonicalEpisodeList, bool) {
row, err := s.queries.GetEpisodeAvailabilityCache(ctx, int64(anime.MalID)) row, err := s.queries.GetEpisodeAvailabilityCache(ctx, int64(anime.MalID))
if err != nil { if err != nil {
s.metrics.ObserveCache("episode_availability_fresh", "miss")
return domain.CanonicalEpisodeList{}, false return domain.CanonicalEpisodeList{}, false
} }
@@ -147,11 +146,10 @@ func (s *EpisodeService) getFreshCached(ctx context.Context, anime domain.Anime)
return domain.CanonicalEpisodeList{}, false return domain.CanonicalEpisodeList{}, false
} }
payload, ok := s.decodeCachedPayload(anime, row.Data, "episode_availability_fresh") payload, ok := s.decodeCachedPayload(anime, row.Data)
if !ok { if !ok {
return domain.CanonicalEpisodeList{}, false return domain.CanonicalEpisodeList{}, false
} }
s.metrics.ObserveCache("episode_availability_fresh", "hit")
observability.Info( observability.Info(
"episodes_cache_served", "episodes_cache_served",
"episodes", "episodes",
@@ -165,23 +163,20 @@ func (s *EpisodeService) getFreshCached(ctx context.Context, anime domain.Anime)
return payload, true return payload, true
} }
func (s *EpisodeService) getDecodedCached(ctx context.Context, anime domain.Anime, metric string) (domain.CanonicalEpisodeList, bool) { func (s *EpisodeService) getDecodedCached(ctx context.Context, anime domain.Anime) (domain.CanonicalEpisodeList, bool) {
row, err := s.queries.GetEpisodeAvailabilityCache(ctx, int64(anime.MalID)) row, err := s.queries.GetEpisodeAvailabilityCache(ctx, int64(anime.MalID))
if err != nil { if err != nil {
s.metrics.ObserveCache(metric, "miss")
return domain.CanonicalEpisodeList{}, false return domain.CanonicalEpisodeList{}, false
} }
payload, ok := s.decodeCachedPayload(anime, row.Data, metric) payload, ok := s.decodeCachedPayload(anime, row.Data)
if !ok { if !ok {
return domain.CanonicalEpisodeList{}, false return domain.CanonicalEpisodeList{}, false
} }
s.metrics.ObserveCache(metric, "hit")
return payload, true return payload, true
} }
func (s *EpisodeService) isFreshEpisodeCache(anime domain.Anime, row db.EpisodeAvailabilityCache, now time.Time) bool { func (s *EpisodeService) isFreshEpisodeCache(anime domain.Anime, row db.EpisodeAvailabilityCache, now time.Time) bool {
if row.NextRefreshAt.Valid && !row.NextRefreshAt.Time.After(now) { if row.NextRefreshAt.Valid && !row.NextRefreshAt.Time.After(now) {
s.metrics.ObserveCache("episode_availability_fresh", "miss")
observability.Info( observability.Info(
"episodes_cache_due_for_refresh", "episodes_cache_due_for_refresh",
"episodes", "episodes",
@@ -194,7 +189,6 @@ func (s *EpisodeService) isFreshEpisodeCache(anime domain.Anime, row db.EpisodeA
return false return false
} }
if anime.Airing && row.UpdatedAt.Before(now.Add(-airingFallbackRefreshInterval)) { if anime.Airing && row.UpdatedAt.Before(now.Add(-airingFallbackRefreshInterval)) {
s.metrics.ObserveCache("episode_availability_fresh", "miss")
observability.Info( observability.Info(
"episodes_cache_too_old_for_airing", "episodes_cache_too_old_for_airing",
"episodes", "episodes",
@@ -209,10 +203,9 @@ func (s *EpisodeService) isFreshEpisodeCache(anime domain.Anime, row db.EpisodeA
return true return true
} }
func (s *EpisodeService) decodeCachedPayload(anime domain.Anime, raw string, metric string) (domain.CanonicalEpisodeList, bool) { func (s *EpisodeService) decodeCachedPayload(anime domain.Anime, raw string) (domain.CanonicalEpisodeList, bool) {
var payload domain.CanonicalEpisodeList var payload domain.CanonicalEpisodeList
if err := json.Unmarshal([]byte(raw), &payload); err != nil { if err := json.Unmarshal([]byte(raw), &payload); err != nil {
s.metrics.ObserveCache(metric, "miss")
observability.Warn( observability.Warn(
"episodes_cached_payload_invalid", "episodes_cached_payload_invalid",
"episodes", "episodes",
@@ -226,7 +219,6 @@ func (s *EpisodeService) decodeCachedPayload(anime domain.Anime, raw string, met
} }
if !isCanonicalEpisodePayloadValid(payload, anime.Episodes) { if !isCanonicalEpisodePayloadValid(payload, anime.Episodes) {
s.metrics.ObserveCache(metric, "miss")
observability.Info( observability.Info(
"episodes_cached_payload_rejected", "episodes_cached_payload_rejected",
"episodes", "episodes",

View File

@@ -45,7 +45,6 @@ func (s *EpisodeService) cachedProviderID(ctx context.Context, anime domain.Anim
Provider: provider.Name(), Provider: provider.Name(),
}) })
if err != nil { if err != nil {
s.metrics.ObserveCache("episode_provider_mapping", "miss")
if errors.Is(err, sql.ErrNoRows) { if errors.Is(err, sql.ErrNoRows) {
return "", false, nil return "", false, nil
} }
@@ -63,15 +62,12 @@ func (s *EpisodeService) cachedProviderID(ctx context.Context, anime domain.Anim
} }
if row.FailedUntil.Valid && row.FailedUntil.Time.After(s.clock.Now()) { if row.FailedUntil.Valid && row.FailedUntil.Time.After(s.clock.Now()) {
s.metrics.ObserveCache("episode_provider_mapping", "hit")
return "", true, fmt.Errorf("cached provider mapping failure active until %s: %s", row.FailedUntil.Time.Format(time.RFC3339), row.LastError) return "", true, fmt.Errorf("cached provider mapping failure active until %s: %s", row.FailedUntil.Time.Format(time.RFC3339), row.LastError)
} }
if strings.TrimSpace(row.ProviderShowID) == "" { if strings.TrimSpace(row.ProviderShowID) == "" {
s.metrics.ObserveCache("episode_provider_mapping", "miss")
return "", false, nil return "", false, nil
} }
s.metrics.ObserveCache("episode_provider_mapping", "hit")
observability.Info( observability.Info(
"episodes_provider_id_cache_hit", "episodes_provider_id_cache_hit",
"episodes", "episodes",

View File

@@ -26,21 +26,19 @@ type EpisodeService struct {
providers []domain.EpisodeAvailabilityProvider providers []domain.EpisodeAvailabilityProvider
clock Clock clock Clock
enabled bool enabled bool
metrics *observability.Metrics
} }
func NewEpisodeService(queries *db.Queries, jikanClient *jikan.Client, providers []domain.EpisodeAvailabilityProvider, enabled bool, metrics *observability.Metrics) domain.EpisodeService { func NewEpisodeService(queries *db.Queries, jikanClient *jikan.Client, providers []domain.EpisodeAvailabilityProvider, enabled bool) domain.EpisodeService {
return NewEpisodeServiceWithClock(queries, jikanClient, providers, enabled, realClock{}, metrics) return NewEpisodeServiceWithClock(queries, jikanClient, providers, enabled, realClock{})
} }
func NewEpisodeServiceWithClock(queries *db.Queries, jikanClient *jikan.Client, providers []domain.EpisodeAvailabilityProvider, enabled bool, clock Clock, metrics *observability.Metrics) *EpisodeService { func NewEpisodeServiceWithClock(queries *db.Queries, jikanClient *jikan.Client, providers []domain.EpisodeAvailabilityProvider, enabled bool, clock Clock) *EpisodeService {
return &EpisodeService{ return &EpisodeService{
queries: queries, queries: queries,
jikan: jikanClient, jikan: jikanClient,
providers: providers, providers: providers,
clock: clock, clock: clock,
enabled: enabled, enabled: enabled,
metrics: metrics,
} }
} }

View File

@@ -11,7 +11,7 @@ import (
const workerInterval = time.Minute const workerInterval = time.Minute
func RegisterWorker(lc fx.Lifecycle, svc domain.EpisodeService, metrics *observability.Metrics) { func RegisterWorker(lc fx.Lifecycle, svc domain.EpisodeService) {
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
lc.Append(fx.Hook{ lc.Append(fx.Hook{
@@ -31,7 +31,6 @@ func RegisterWorker(lc fx.Lifecycle, svc domain.EpisodeService, metrics *observa
err := svc.RefreshTrackedDue(tickCtx, 25) err := svc.RefreshTrackedDue(tickCtx, 25)
tickCancel() tickCancel()
if err != nil { if err != nil {
metrics.ObserveWorkerTick("episodes_availability", err)
observability.Warn( observability.Warn(
"episodes_worker_tick_failed", "episodes_worker_tick_failed",
"episodes", "episodes",
@@ -41,8 +40,6 @@ func RegisterWorker(lc fx.Lifecycle, svc domain.EpisodeService, metrics *observa
}, },
err, err,
) )
} else {
metrics.ObserveWorkerTick("episodes_availability", nil)
} }
select { select {