From ba012736c9ebb55cea3bf9140694c9862acc1a73 Mon Sep 17 00:00:00 2001 From: "2569718930@qq.com" <2569718930@qq.com> Date: Wed, 10 Jun 2026 14:34:13 +0800 Subject: [PATCH] Tune city detail batch limits --- docker-compose.yml | 6 +++--- tests/test_deployment_runtime_config.py | 6 +++--- tests/test_web_observability.py | 7 ++++++- web/services/city_api.py | 14 +++++++------- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 5bbc2af5..149f4a82 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -101,9 +101,9 @@ services: environment: POLYWEATHER_REDIS_URL: ${POLYWEATHER_REDIS_URL:-redis://polyweather_redis:6379/0} POLYWEATHER_COLLECTOR_PATCH_ENDPOINT: '' - POLYWEATHER_CITY_DETAIL_BATCH_CONCURRENCY: ${POLYWEATHER_CITY_DETAIL_BATCH_CONCURRENCY:-1} - POLYWEATHER_CITY_DETAIL_BATCH_GLOBAL_CONCURRENCY: ${POLYWEATHER_CITY_DETAIL_BATCH_GLOBAL_CONCURRENCY:-1} - POLYWEATHER_CITY_DETAIL_BATCH_PARTIAL_TIMEOUT_MS: ${POLYWEATHER_CITY_DETAIL_BATCH_PARTIAL_TIMEOUT_MS:-3000} + POLYWEATHER_CITY_DETAIL_BATCH_CONCURRENCY: ${POLYWEATHER_CITY_DETAIL_BATCH_CONCURRENCY:-3} + POLYWEATHER_CITY_DETAIL_BATCH_GLOBAL_CONCURRENCY: ${POLYWEATHER_CITY_DETAIL_BATCH_GLOBAL_CONCURRENCY:-2} + POLYWEATHER_CITY_DETAIL_BATCH_PARTIAL_TIMEOUT_MS: ${POLYWEATHER_CITY_DETAIL_BATCH_PARTIAL_TIMEOUT_MS:-8000} POLYWEATHER_OBSERVATION_COLLECTOR_AMOS_SEC: ${POLYWEATHER_OBSERVATION_COLLECTOR_AMOS_SEC:-60} POLYWEATHER_OBSERVATION_COLLECTOR_AMSC_SEC: ${POLYWEATHER_OBSERVATION_COLLECTOR_AMSC_SEC:-180} POLYWEATHER_OBSERVATION_COLLECTOR_COWIN_SEC: ${POLYWEATHER_OBSERVATION_COLLECTOR_COWIN_SEC:-60} diff --git a/tests/test_deployment_runtime_config.py b/tests/test_deployment_runtime_config.py index c4317fee..80e450b9 100644 --- a/tests/test_deployment_runtime_config.py +++ b/tests/test_deployment_runtime_config.py @@ -98,9 +98,9 @@ def test_docker_compose_isolates_collector_from_web_and_bot_services(): assert "POLYWEATHER_OBSERVATION_COLLECTOR_ENABLED: 'false'" in bot_block assert "POLYWEATHER_OBSERVATION_COLLECTOR_ENABLED: 'false'" in web_block assert "POLYWEATHER_OBSERVATION_COLLECTOR_ENABLED: 'true'" in collector_block - assert "POLYWEATHER_CITY_DETAIL_BATCH_CONCURRENCY: ${POLYWEATHER_CITY_DETAIL_BATCH_CONCURRENCY:-1}" in web_block - assert "POLYWEATHER_CITY_DETAIL_BATCH_GLOBAL_CONCURRENCY: ${POLYWEATHER_CITY_DETAIL_BATCH_GLOBAL_CONCURRENCY:-1}" in web_block - assert "POLYWEATHER_CITY_DETAIL_BATCH_PARTIAL_TIMEOUT_MS: ${POLYWEATHER_CITY_DETAIL_BATCH_PARTIAL_TIMEOUT_MS:-3000}" in web_block + assert "POLYWEATHER_CITY_DETAIL_BATCH_CONCURRENCY: ${POLYWEATHER_CITY_DETAIL_BATCH_CONCURRENCY:-3}" in web_block + assert "POLYWEATHER_CITY_DETAIL_BATCH_GLOBAL_CONCURRENCY: ${POLYWEATHER_CITY_DETAIL_BATCH_GLOBAL_CONCURRENCY:-2}" in web_block + assert "POLYWEATHER_CITY_DETAIL_BATCH_PARTIAL_TIMEOUT_MS: ${POLYWEATHER_CITY_DETAIL_BATCH_PARTIAL_TIMEOUT_MS:-8000}" in web_block assert "UVICORN_WORKERS: ${UVICORN_WORKERS:-2}" in web_block assert "POLYWEATHER_COLLECTOR_PATCH_ENDPOINT: ''" in bot_block assert "POLYWEATHER_COLLECTOR_PATCH_ENDPOINT: ''" in web_block diff --git a/tests/test_web_observability.py b/tests/test_web_observability.py index bf1fb670..166b0073 100644 --- a/tests/test_web_observability.py +++ b/tests/test_web_observability.py @@ -969,7 +969,12 @@ def test_chart_detail_payload_uses_threadpool_and_reuses_short_cache(monkeypatch def test_city_detail_batch_partial_timeout_default_stays_below_proxy_budget(monkeypatch): monkeypatch.delenv("POLYWEATHER_CITY_DETAIL_BATCH_PARTIAL_TIMEOUT_MS", raising=False) - assert city_api._city_detail_batch_partial_timeout_seconds() == 3.0 + monkeypatch.delenv("POLYWEATHER_CITY_DETAIL_BATCH_CONCURRENCY", raising=False) + monkeypatch.delenv("POLYWEATHER_CITY_DETAIL_BATCH_GLOBAL_CONCURRENCY", raising=False) + + assert city_api._city_detail_batch_concurrency() == 3 + assert city_api._city_detail_batch_global_concurrency() == 2 + assert city_api._city_detail_batch_partial_timeout_seconds() == 8.0 def test_city_detail_batch_returns_busy_when_global_builder_slot_is_full(monkeypatch): diff --git a/web/services/city_api.py b/web/services/city_api.py index 702c5dd0..7f339cd3 100644 --- a/web/services/city_api.py +++ b/web/services/city_api.py @@ -936,17 +936,17 @@ async def _build_city_detail_batch_item_async( def _city_detail_batch_concurrency() -> int: try: - value = int(os.getenv("POLYWEATHER_CITY_DETAIL_BATCH_CONCURRENCY", "1") or "1") + value = int(os.getenv("POLYWEATHER_CITY_DETAIL_BATCH_CONCURRENCY", "3") or "3") except ValueError: - value = 1 + value = 3 return max(1, min(4, value)) def _city_detail_batch_global_concurrency() -> int: try: - value = int(os.getenv("POLYWEATHER_CITY_DETAIL_BATCH_GLOBAL_CONCURRENCY", "1") or "1") + value = int(os.getenv("POLYWEATHER_CITY_DETAIL_BATCH_GLOBAL_CONCURRENCY", "2") or "2") except ValueError: - value = 1 + value = 2 return max(1, min(4, value)) @@ -963,11 +963,11 @@ def _city_detail_batch_build_semaphore() -> threading.BoundedSemaphore: def _city_detail_batch_partial_timeout_seconds() -> Optional[float]: try: timeout_ms = int( - os.getenv("POLYWEATHER_CITY_DETAIL_BATCH_PARTIAL_TIMEOUT_MS", "3000") - or "3000" + os.getenv("POLYWEATHER_CITY_DETAIL_BATCH_PARTIAL_TIMEOUT_MS", "8000") + or "8000" ) except ValueError: - timeout_ms = 3000 + timeout_ms = 8000 if timeout_ms <= 0: return None return max(0.001, min(60.0, timeout_ms / 1000.0))