From 97660833abdf4b196fc96eeb52a7899c299f1b55 Mon Sep 17 00:00:00 2001 From: IK Date: Thu, 10 Sep 2026 17:55:30 +0700 Subject: [PATCH] A02: Fix double cooldown reservation bug in main() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: main() called both enforce_fetch_interval() and mark_fetch(), which both now call check_and_reserve(). On cold start: 1. enforce_fetch_interval() → check_and_reserve() → SUCCESS (reserves) 2. mark_fetch() → check_and_reserve() → FAILS (cooldown now active) This prevented HTTP from ever being called on cold start. Fix: - Removed duplicate calls to enforce_fetch_interval() and mark_fetch() - Single check_and_reserve() call before fetch_html() - enforce_fetch_interval() and mark_fetch() remain as legacy wrappers Verification: - All 18 community_cli tests pass - Code analysis confirms single check_and_reserve() call in main() - check_and_reserve() is atomic with exclusive lock for check+reserve --- rf4_research/community_cli.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/rf4_research/community_cli.py b/rf4_research/community_cli.py index 71fc71f..76a61e3 100644 --- a/rf4_research/community_cli.py +++ b/rf4_research/community_cli.py @@ -275,9 +275,8 @@ def main(argv: list[str] | None = None) -> int: url = args.url or default_url try: site_key = fetch_site_key(url) - enforce_fetch_interval(site_key, state_file=args.state_file) - # Reserve before network I/O: failed attempts count toward the limit too. - mark_fetch(site_key, state_file=args.state_file) + # Single atomic check-and-reserve before network I/O: failed attempts count toward the limit too. + check_and_reserve(site_key, state_file=args.state_file) html = fetch_html(url) records = (parse(html, source_url=url) if args.source in DETAIL_SOURCES else parse(html))[:args.limit] except Exception as exc: