video enrichment: stop OMDb traceback spam from the detail/drawer path too
the earlier latch only covered _backfill_ratings. _fill_tmdb_ratings (hit by tmdb_full_detail → detail pages, the download drawer's meta endpoint, the airing automation's status lookups) still re-hit OMDb once per title and dumped a traceback each time once over quota. now it shares the same _omdb_blocked latch: checks it before calling, sets it + logs ONE quiet warning on OMDbAuthError. (the bulk OMDb worker already cools down + auto-resumes, so it was never the spammer.) tested.
This commit is contained in:
parent
75f23641b3
commit
11c0c62a7e
2 changed files with 32 additions and 1 deletions
|
|
@ -567,13 +567,19 @@ class VideoEnrichmentEngine:
|
||||||
def _fill_tmdb_ratings(self, d) -> None:
|
def _fill_tmdb_ratings(self, d) -> None:
|
||||||
imdb_id = d.get("imdb_id")
|
imdb_id = d.get("imdb_id")
|
||||||
ow = self.workers.get("omdb")
|
ow = self.workers.get("omdb")
|
||||||
if not imdb_id or not ow or not getattr(ow.client, "enabled", False):
|
# share the same daily-limit latch as _backfill_ratings — once OMDb is over quota,
|
||||||
|
# every detail fetch would otherwise re-hit it and dump a traceback per title.
|
||||||
|
if (not imdb_id or not ow or not getattr(ow.client, "enabled", False)
|
||||||
|
or getattr(self, "_omdb_blocked", False)):
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
r = ow.client.ratings(imdb_id) or {}
|
r = ow.client.ratings(imdb_id) or {}
|
||||||
for k in ("imdb_rating", "rt_rating", "metacritic"):
|
for k in ("imdb_rating", "rt_rating", "metacritic"):
|
||||||
if r.get(k) is not None:
|
if r.get(k) is not None:
|
||||||
d[k] = r[k]
|
d[k] = r[k]
|
||||||
|
except OMDbAuthError as e:
|
||||||
|
self._omdb_blocked = True
|
||||||
|
logger.warning("OMDb ratings paused for this run: %s", e)
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.exception("tmdb_detail ratings failed for %s", imdb_id)
|
logger.exception("tmdb_detail ratings failed for %s", imdb_id)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,31 @@ def test_omdb_limit_latches_off_and_stops_hammering():
|
||||||
assert rc.n == 1 # only the first attempt ever reached OMDb
|
assert rc.n == 1 # only the first attempt ever reached OMDb
|
||||||
|
|
||||||
|
|
||||||
|
def test_tmdb_detail_ratings_share_the_same_latch():
|
||||||
|
# the detail/drawer path (_fill_tmdb_ratings) must honour + set the SAME latch — it was
|
||||||
|
# the source of the per-title traceback spam on the download drawer / detail pages.
|
||||||
|
from core.video.enrichment.engine import VideoEnrichmentEngine
|
||||||
|
from core.video.enrichment.clients import OMDbAuthError
|
||||||
|
|
||||||
|
class _RC:
|
||||||
|
enabled = True
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.n = 0
|
||||||
|
|
||||||
|
def ratings(self, imdb):
|
||||||
|
self.n += 1
|
||||||
|
raise OMDbAuthError("Request limit reached!")
|
||||||
|
|
||||||
|
eng = VideoEnrichmentEngine.__new__(VideoEnrichmentEngine)
|
||||||
|
rc = _RC()
|
||||||
|
eng.workers = {"omdb": type("W", (), {"client": rc})()}
|
||||||
|
eng._fill_tmdb_ratings({"imdb_id": "tt1"}) # hits the limit → latches (no raise out)
|
||||||
|
assert getattr(eng, "_omdb_blocked", False) is True
|
||||||
|
eng._fill_tmdb_ratings({"imdb_id": "tt2"}) # short-circuits before calling OMDb
|
||||||
|
assert rc.n == 1
|
||||||
|
|
||||||
|
|
||||||
# ── wiring contract ───────────────────────────────────────────────────────────
|
# ── wiring contract ───────────────────────────────────────────────────────────
|
||||||
def test_seeded_before_the_airing_automation():
|
def test_seeded_before_the_airing_automation():
|
||||||
import core.automation_engine as ae
|
import core.automation_engine as ae
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue