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'