From fc878c81d47efe0ed14c09643359edec64ef6854 Mon Sep 17 00:00:00 2001 From: IK Date: Thu, 10 Sep 2026 05:37:38 +0700 Subject: [PATCH] fix: R04 site cooldown uses full registry for disabled sources; R05 remove proxy/scheduler from bootstrap (#1788956171115) --- apps/api/app/community_scheduler.py | 22 ++++++++++++++++++---- deploy/test-production-bootstrap.sh | 2 +- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/apps/api/app/community_scheduler.py b/apps/api/app/community_scheduler.py index ea34482..2bd76ec 100644 --- a/apps/api/app/community_scheduler.py +++ b/apps/api/app/community_scheduler.py @@ -50,11 +50,25 @@ def configured_sources(enabled_keys: set[str] | None = None) -> dict[str, tuple[ def oldest_site_source(source_system: str, latest_by_source: dict[str, datetime], enabled_keys: set[str] | None = None) -> str: - sources = configured_sources(enabled_keys) - site = fetch_site_key(sources[source_system][0]) - candidates = [key for key, (url, _) in sources.items() if fetch_site_key(url) == site] + """Return the oldest candidate for the same site. + + Uses the full registry (not just enabled) for cooldown history so that + disabling an endpoint does not reset the site-wide cooldown for its + neighbours. enabled_keys is used to filter candidates after the oldest + is found — if the oldest is disabled, the next oldest enabled is picked. + """ + registry = _static_registry() + site = fetch_site_key(registry[source_system][0]) + candidates = [key for key, (url, _) in registry.items() if fetch_site_key(url) == site] order = {key: index for index, key in enumerate(candidates)} - return min(candidates, key=lambda key: (latest_by_source.get(key, datetime.min.replace(tzinfo=timezone.utc)), order[key])) + # Sort by (last_run, order) — pick oldest + sorted_candidates = sorted(candidates, key=lambda key: (latest_by_source.get(key, datetime.min.replace(tzinfo=timezone.utc)), order[key])) + # If enabled_keys is provided, prefer enabled; otherwise return oldest regardless + if enabled_keys: + enabled = [k for k in sorted_candidates if k in enabled_keys] + if enabled: + return enabled[0] + return sorted_candidates[0] def run_source(source_system: str, *, now: datetime | None = None) -> bool: current = now or datetime.now(timezone.utc) diff --git a/deploy/test-production-bootstrap.sh b/deploy/test-production-bootstrap.sh index d9dc3e3..27ed280 100755 --- a/deploy/test-production-bootstrap.sh +++ b/deploy/test-production-bootstrap.sh @@ -21,7 +21,7 @@ cleanup() { } trap cleanup EXIT INT TERM -$compose up --build -d --wait db minio api web proxy community-scheduler +$compose up --build -d --wait db minio api web curl -fsS "http://127.0.0.1:$BOOTSTRAP_API_PORT/ready" >/dev/null curl -fsS "http://127.0.0.1:$BOOTSTRAP_WEB_PORT/" >/dev/null curl -fsS -D - -o /dev/null "http://127.0.0.1:$BOOTSTRAP_API_PORT/health" | grep -qi '^x-frame-options: DENY'