fix(tradein): бюджет по времени в geocode-missing — cron не таймаутит #422

Merged
lekss361 merged 1 commit from fix/tradein-geocode-time-budget into main 2026-05-22 09:37:42 +00:00

View file

@ -5,8 +5,8 @@
from __future__ import annotations
import asyncio
import logging
import time
from typing import Annotated, Literal
from fastapi import APIRouter, Depends, Header, HTTPException
@ -145,8 +145,9 @@ async def geocode_missing(
"""Геокодинг listings ИЛИ deals у которых нет lat/lon (используя address).
target=listings (по умолч.) объявления Cian/N1; target=deals сделки Росреестра.
Чанк-обработка: limit=100 ~150-200с (Nominatim 1 req/sec). cron вызывает
в цикле пока `remaining` > 0.
Чанк-обработка с бюджетом по времени (~240с, заведомо меньше cron
`curl -m 320`): за вызов геокодим сколько успеваем, остаток уходит в
`remaining`, cron вызывает в цикле пока `remaining` > 0.
geocode_tried_at: после КАЖДОЙ попытки (успех/провал) ставим NOW(). Failed-
адреса не выбираются повторно 7 дней cron-loop завершается, не зацикливается.
@ -175,9 +176,21 @@ async def geocode_missing(
{"limit": limit},
).mappings().all()
# Бюджет по времени: геокодинг упирается в Nominatim (1 req/sec + typo-тиры
# на провалах), 100 адресов могут не уложиться в cron-таймаут `curl -m 320`.
# Выходим из цикла заведомо раньше — remaining > 0 заставит cron продолжить.
budget_sec = 240.0
started = time.monotonic()
geocoded = 0
skipped = 0
for row in rows:
if time.monotonic() - started > budget_sec:
logger.info(
"geocode-missing: бюджет %.0fс исчерпан, обработано %d — cron продолжит",
budget_sec, geocoded + skipped,
)
break
clean = _clean_address_for_geocode(row["address"])
result = await geocode(clean, db)
if result is None: