fix(naver-fetch): realestate base :18800 + 동별 ingest + 180s no-retry
This commit is contained in:
@@ -8,40 +8,47 @@ import httpx
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
_MAX_ATTEMPTS = 3
|
||||
_RETRY_STATUSES = {429, 500, 502, 503, 504}
|
||||
_TARGETS_TIMEOUT = 15.0
|
||||
_INGEST_TIMEOUT = 180.0 # 첫 실행 bulk upsert/매칭/알림이 느림 (초 단위 수십)
|
||||
|
||||
|
||||
class NASClient:
|
||||
def __init__(self, base_url: str, api_key: str, timeout: float = 15.0):
|
||||
def __init__(self, base_url: str, api_key: str):
|
||||
self._base_url = base_url.rstrip("/")
|
||||
self._api_key = api_key
|
||||
self._client = httpx.AsyncClient(timeout=timeout)
|
||||
self._client = httpx.AsyncClient()
|
||||
|
||||
async def close(self) -> None:
|
||||
await self._client.aclose()
|
||||
|
||||
async def get_targets(self) -> dict:
|
||||
return await self._request("GET", "/api/internal/realestate/targets")
|
||||
return await self._request("GET", "/api/internal/realestate/targets",
|
||||
timeout=_TARGETS_TIMEOUT, max_attempts=3)
|
||||
|
||||
async def post_ingest(self, fetched_at: str, batches: list[dict]) -> dict:
|
||||
# ingest는 재시도 안 함(max_attempts=1) — 타임아웃 후 재전송 시
|
||||
# NAS가 같은 batch를 재처리/재알림할 위험. 실패 시 다음 사이클에 재시도.
|
||||
return await self._request(
|
||||
"POST", "/api/internal/realestate/listings-ingest",
|
||||
json={"fetched_at": fetched_at, "batches": batches})
|
||||
json={"fetched_at": fetched_at, "batches": batches},
|
||||
timeout=_INGEST_TIMEOUT, max_attempts=1)
|
||||
|
||||
async def _request(self, method: str, path: str, **kwargs) -> dict:
|
||||
async def _request(self, method: str, path: str, *, timeout: float,
|
||||
max_attempts: int, **kwargs) -> dict:
|
||||
url = f"{self._base_url}{path}"
|
||||
headers = {"X-Internal-Key": self._api_key}
|
||||
for attempt in range(_MAX_ATTEMPTS):
|
||||
for attempt in range(max_attempts):
|
||||
try:
|
||||
resp = await self._client.request(method, url, headers=headers, **kwargs)
|
||||
if resp.status_code in _RETRY_STATUSES and attempt < _MAX_ATTEMPTS - 1:
|
||||
resp = await self._client.request(method, url, headers=headers,
|
||||
timeout=timeout, **kwargs)
|
||||
if resp.status_code in _RETRY_STATUSES and attempt < max_attempts - 1:
|
||||
await asyncio.sleep(2 ** attempt)
|
||||
continue
|
||||
resp.raise_for_status()
|
||||
return resp.json()
|
||||
except httpx.TimeoutException:
|
||||
if attempt < _MAX_ATTEMPTS - 1:
|
||||
if attempt < max_attempts - 1:
|
||||
await asyncio.sleep(2 ** attempt)
|
||||
continue
|
||||
raise
|
||||
|
||||
Reference in New Issue
Block a user