Skip to content

Commit 1d75fdd

Browse files
committed
fix(verify): skip fully cached records before capping the check-urls frontier
The frontier took the top --max unverified records by score before dropping fresh cached URLs, so the same already-checked records filled the quota on every run and lower-ranked green records were never checked. 848 green records (763 CPUs) had never had a citation checked and could not be promoted. Refs #98 Refs GetTechAPI/TechAPI#297
1 parent 47a976a commit 1d75fdd

2 files changed

Lines changed: 41 additions & 5 deletions

File tree

‎app/verify/cli.py‎

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,19 @@ def cmd_check_urls(args: argparse.Namespace) -> int:
416416
now_year = offline.now_year_today()
417417
categories = tuple(args.category) if args.category else CATEGORIES
418418

419+
cache = http_check.load_cache()
420+
now = datetime.now(UTC)
421+
422+
def _fresh(u: str) -> bool:
423+
return u in cache and http_check.is_fresh(cache[u], now, args.ttl_days)
424+
419425
frontier = _ranked_unverified(records, soc_release, now_year, categories)
426+
if not args.recheck:
427+
# Records whose citations are all fresh would fill the quota every run and
428+
# starve lower-ranked records that were never checked.
429+
frontier = [rec for rec in frontier if not all(
430+
_fresh(u) for u in rec.data.get("source_urls", []) if isinstance(u, str)
431+
)]
420432
if args.max is not None:
421433
frontier = frontier[: args.max]
422434

@@ -425,14 +437,10 @@ def cmd_check_urls(args: argparse.Namespace) -> int:
425437
urls.extend(u for u in rec.data.get("source_urls", []) if isinstance(u, str))
426438
targets = http_check.dedupe_urls(urls)
427439

428-
cache = http_check.load_cache()
429-
now = datetime.now(UTC)
430440
if args.recheck:
431441
todo = targets
432442
else:
433-
todo = [u for u in targets if not (
434-
u in cache and http_check.is_fresh(cache[u], now, args.ttl_days)
435-
)]
443+
todo = [u for u in targets if not _fresh(u)]
436444

437445
print(
438446
f"check-urls: {len(frontier)} record(s) -> {len(targets)} unique URL(s); "

‎tests/verify/test_http_check.py‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,3 +213,31 @@ def test_host_backoff_is_capped():
213213
for _ in range(20):
214214
limiter.back_off("gsmarena.com")
215215
assert limiter.interval_for("gsmarena.com") == http_check.MAX_HOST_INTERVAL_S
216+
217+
218+
def test_check_urls_frontier_skips_fully_cached_records(monkeypatch, capsys):
219+
"""Already-checked top records must not fill --max and starve unchecked ones."""
220+
import argparse
221+
from datetime import datetime
222+
223+
from app.verify import cli
224+
from app.verify.common import Record
225+
226+
recs = [Record("cpu", f"cpu/{i}.json",
227+
{"slug": f"c{i}", "verified": False,
228+
"source_urls": [f"https://en.wikipedia.org/wiki/C{i}"]}) for i in range(3)]
229+
now = datetime.now(UTC).strftime("%Y-%m-%dT%H:%M:%SZ")
230+
cache = {"https://en.wikipedia.org/wiki/C0": {"alive": False, "status": 404, "checked_at": now}}
231+
monkeypatch.setattr(cli, "load_all", lambda *a, **k: {"cpu": recs})
232+
monkeypatch.setattr(cli, "foreign_key_sets", lambda r: (set(), set(), {}))
233+
monkeypatch.setattr(cli, "_ranked_unverified", lambda *a: list(recs))
234+
monkeypatch.setattr(http_check, "load_cache", lambda *a: dict(cache))
235+
monkeypatch.setattr(http_check, "is_fresh", lambda e, now, ttl: True)
236+
checked = []
237+
monkeypatch.setattr(http_check, "check_urls",
238+
lambda urls, **k: checked.extend(urls) or [])
239+
monkeypatch.setattr(http_check, "save_cache", lambda *a, **k: None)
240+
args = argparse.Namespace(category=["cpu"], max=1, recheck=False, ttl_days=30,
241+
workers=1, min_interval=0.0)
242+
cli.cmd_check_urls(args)
243+
assert checked == ["https://en.wikipedia.org/wiki/C1"]

0 commit comments

Comments
 (0)