geocode-бэкфилл: budget_sec проверяется только между батчами — прогон ушёл на 175 % бюджета #3151

Closed
opened 2026-08-27 16:01:31 +00:00 by bot-backend · 0 comments
Collaborator

Найдено при проверке приёмки #2953.

Что происходит

run_geocode_missing_listings принимает budget_sec (default 1800) и рекламирует его как «максимальное время прогона». Фактически проверка стоит только между батчами:

tradein-mvp/backend/app/tasks/geocode_missing.py:402

while True:
    res = await geocode_missing_listings(db, batch_size=batch_size, ...)
    ...
    if res.addresses_total == 0: break
    if res.addresses_total < batch_size: break   # дренаж
    if elapsed > budget_sec: break                # ← единственная проверка бюджета

Внутри geocode_missing_listings цикл идёт по всем batch_size адресам (default 200) и часов не смотрит вовсе. То есть потолок прогона на самом деле не budget_sec, а budget_sec + время одного полного батча.

Замер

Прогон scrape_runs.id=5017 (27.08 03:21 UTC):

params   {"batch_size": 200, "budget_sec": 1800}
counters {"checked": 95, "saved": 0, "skipped": 95}
длительность 3150 с  ← 175 % от бюджета

Вышел он при этом не по бюджету, а по дренажу (95 < 200): бюджетная ветка за 52 минуты не выполнилась ни разу, потому что до неё дело доходит только после конца батча.

Почему стало заметно только сейчас

До общего ограничителя темпа (#2953, смержен 20.08) адрес стоил ~1.9 с, полный батч из 200 — около 6 минут, и перебор бюджета был в пределах шума. После ограничителя средняя цена адреса 4.5 с, а на трудном хвосте (tier-1 + до 4 typo-вариантов, каждый под паузой 1 с, плюс @retry(stop_after_attempt(3))) доходит до 33 с. Полный батч из 200 таких адресов — до ~110 минут поверх бюджета.

Сейчас это не больно: очередь 381 пара, прогоны заканчиваются дренажем. Станет больно, когда очередь вырастет (московский объём — отдельная тема, #2996) либо когда доля трудного хвоста ещё поднимется: окно расписания 06:00–09:00 UTC, а прогон способен уехать за него.

Что сделать

Проверять бюджет внутри батча — передать дедлайн в geocode_missing_listings и выходить из цикла по адресам, возвращая уже накопленные счётчики (частичный батч — штатный результат, следующий прогон доберёт остаток; geocode_tried_at уже проставлен только у обработанных).

Приёмка: прогон с искусственно малым budget_sec завершается в пределах бюджета + один адрес, а не + один батч; счётчики частичного батча не теряются.

Refs #2953

Найдено при проверке приёмки #2953. ## Что происходит `run_geocode_missing_listings` принимает `budget_sec` (default 1800) и рекламирует его как «максимальное время прогона». Фактически проверка стоит **только между батчами**: `tradein-mvp/backend/app/tasks/geocode_missing.py:402` ```python while True: res = await geocode_missing_listings(db, batch_size=batch_size, ...) ... if res.addresses_total == 0: break if res.addresses_total < batch_size: break # дренаж if elapsed > budget_sec: break # ← единственная проверка бюджета ``` Внутри `geocode_missing_listings` цикл идёт по всем `batch_size` адресам (default 200) и часов не смотрит вовсе. То есть потолок прогона на самом деле не `budget_sec`, а `budget_sec + время одного полного батча`. ## Замер Прогон `scrape_runs.id=5017` (27.08 03:21 UTC): ``` params {"batch_size": 200, "budget_sec": 1800} counters {"checked": 95, "saved": 0, "skipped": 95} длительность 3150 с ← 175 % от бюджета ``` Вышел он при этом **не по бюджету, а по дренажу** (95 < 200): бюджетная ветка за 52 минуты не выполнилась ни разу, потому что до неё дело доходит только после конца батча. ## Почему стало заметно только сейчас До общего ограничителя темпа (#2953, смержен 20.08) адрес стоил ~1.9 с, полный батч из 200 — около 6 минут, и перебор бюджета был в пределах шума. После ограничителя средняя цена адреса 4.5 с, а на трудном хвосте (tier-1 + до 4 typo-вариантов, каждый под паузой 1 с, плюс `@retry(stop_after_attempt(3))`) доходит до 33 с. Полный батч из 200 таких адресов — до ~110 минут поверх бюджета. Сейчас это не больно: очередь 381 пара, прогоны заканчиваются дренажем. Станет больно, когда очередь вырастет (московский объём — отдельная тема, #2996) либо когда доля трудного хвоста ещё поднимется: окно расписания 06:00–09:00 UTC, а прогон способен уехать за него. ## Что сделать Проверять бюджет **внутри** батча — передать дедлайн в `geocode_missing_listings` и выходить из цикла по адресам, возвращая уже накопленные счётчики (частичный батч — штатный результат, следующий прогон доберёт остаток; `geocode_tried_at` уже проставлен только у обработанных). Приёмка: прогон с искусственно малым `budget_sec` завершается в пределах бюджета + один адрес, а не + один батч; счётчики частичного батча не теряются. Refs #2953
bot-backend added the
bug
priority/p3
scope/backend
tech-debt
tradein
labels 2026-08-27 16:01:56 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#3151
No description provided.