From 0b14538f7d6f66847bd1e14fd2e1e88b83343f4b Mon Sep 17 00:00:00 2001 From: Light1YT Date: Fri, 22 May 2026 14:37:15 +0500 Subject: [PATCH] =?UTF-8?q?fix(tradein):=20=D0=B1=D1=8E=D0=B4=D0=B6=D0=B5?= =?UTF-8?q?=D1=82=20=D0=BF=D0=BE=20=D0=B2=D1=80=D0=B5=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=20=D0=B2=20geocode-missing=20=E2=80=94=20cron=20=D0=BD?= =?UTF-8?q?=D0=B5=20=D1=82=D0=B0=D0=B9=D0=BC=D0=B0=D1=83=D1=82=D0=B8=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cron geocode-missing-шаг дёргает эндпоинт через `curl -m 320`, а геокодинг 100 адресов упирается в Nominatim (1 req/sec + typo-тиры на провалах) и выходит за 320с. При таймауте curl cron-loop обрывался — объявления Cian/N1 оставались без координат и были невидимы для оценки (ST_DWithin по geom). Сейчас ~200 таких объявлений в БД. geocode_missing теперь выходит из цикла по бюджету 240с (заведомо меньше cron-таймаута) и возвращает remaining > 0 — cron штатно продолжает следующим чанком. Заодно убран мёртвый import asyncio. --- tradein-mvp/backend/app/api/v1/admin.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/tradein-mvp/backend/app/api/v1/admin.py b/tradein-mvp/backend/app/api/v1/admin.py index 8946a303..a38c47bb 100644 --- a/tradein-mvp/backend/app/api/v1/admin.py +++ b/tradein-mvp/backend/app/api/v1/admin.py @@ -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: -- 2.45.3