From a6c86e88ea263b1d31b58d085c2e885d2ddabe6c Mon Sep 17 00:00:00 2001 From: bot-backend Date: Thu, 17 Sep 2026 12:51:44 +0500 Subject: [PATCH] =?UTF-8?q?fix(tradein/avito):=20=D0=B4=D0=B8=D0=B0=D0=B3?= =?UTF-8?q?=D0=BD=D0=BE=D0=B7=20=D0=B1=D0=BB=D0=BE=D0=BA=D0=BE=D0=B2=20?= =?UTF-8?q?=D0=BB=D0=BE=D0=B6=D0=B8=D1=82=D1=81=D1=8F=20=D0=B2=20counters?= =?UTF-8?q?=20=D0=BB=D1=8E=D0=B1=D0=BE=D0=B3=D0=BE=20=D1=84=D0=B8=D0=BD?= =?UTF-8?q?=D0=B0=D0=BB=D0=B0=20=D0=B4=D0=BE=D0=B1=D0=BE=D1=80=D0=B0,=20?= =?UTF-8?q?=D0=BD=D0=B5=20=D1=82=D0=BE=D0=BB=D1=8C=D0=BA=D0=BE=20'banned'?= =?UTF-8?q?=20(#3288)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Пункт 5 из комментария 05.09: ban_kind пишется только у banned-прогонов, у done/failed диагноза в БД нет. Прод: 7193, 7218, 7264, 7302 — по 1600 попыток, ~1599 блоков, status='done', counters без ban_kinds; что это были отказы сайдкара, а не площадки, видно лишь по косвенному признаку (мелкая block_streak_histogram считает только platform-серии). mark_backfill_finished кладёт перепись в counters только на ветке бана. Задача теперь кладёт counters.ban_kinds сама перед любым финализатором (mark_backfill_finished / mark_failed пустого пула). Статусы и колонка ban_kind не тронуты — контракты #3196/#2764 как были. Тест по значению: 20 отказов сайдкара + 10 успехов — counters, уходящие в финализатор, несут {"infra": 20}. Фальсификация: без строки — «assert None == {'infra': 20}». Стоп-кран для infra-серии (вторая половина п.5) — отдельным коммитом #3439. Co-Authored-By: Claude Opus 5 --- .../app/tasks/avito_detail_backfill.py | 6 ++++++ .../tests/test_3288b_block_kind_ratio.py | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/tradein-mvp/backend/app/tasks/avito_detail_backfill.py b/tradein-mvp/backend/app/tasks/avito_detail_backfill.py index 77332fa6..10041b4f 100644 --- a/tradein-mvp/backend/app/tasks/avito_detail_backfill.py +++ b/tradein-mvp/backend/app/tasks/avito_detail_backfill.py @@ -1023,6 +1023,12 @@ async def run_avito_detail_backfill( counters.duration_sec = time.monotonic() - start current_counters = counters.to_dict() + # #3288 п.5: перепись диагнозов блоков — в counters ЛЮБОГО финала, а не только + # 'banned' (mark_backfill_finished кладёт её лишь на ветке бана). Прогоны + # 7193/7264/7302 (1600 попыток, ~1599 блоков, status='done') ушли без диагноза + # в БД: чей был отказ — площадки или нашего тракта — SQL'ем не узнать. + if block_ban_kinds: + current_counters["ban_kinds"] = dict(block_ban_kinds) # type: ignore[assignment] # #3184: гистограмма длин пачек блоков (streak -> сколько раз встретилась) -- # иначе эффект правки на #2674-статистике нечем измерить постфактум. finalize() # досчитывает хвостовую пачку, если прогон оборвался посреди серии. diff --git a/tradein-mvp/backend/tests/test_3288b_block_kind_ratio.py b/tradein-mvp/backend/tests/test_3288b_block_kind_ratio.py index 61fd0460..7d3ec9c9 100644 --- a/tradein-mvp/backend/tests/test_3288b_block_kind_ratio.py +++ b/tradein-mvp/backend/tests/test_3288b_block_kind_ratio.py @@ -229,6 +229,25 @@ async def test_sidecar_run_walks_the_whole_snapshot_and_is_not_banned() -> None: ) +@pytest.mark.asyncio +async def test_done_run_keeps_ban_kinds_in_counters() -> None: + """#3288 п.5: диагноз доезжает в counters и у прогона, который не 'banned'. + + Прогоны 7193/7264/7302 (1600 попыток, ~1599 отказов сайдкара, status='done') легли + в БД без ban_kinds: перепись писалась в counters только на ветке бана. + """ + fetches: list[Any] = [AvitoSidecarUnavailableError("sidecar 503") for _ in range(20)] + fetches += [MagicMock() for _ in range(10)] + + _, runs = await _run_avito(fetches, snapshot_size=30) + + written = runs.mark_backfill_finished.call_args.args[2] + assert written.get("ban_kinds") == {BAN_KIND_INFRA: 20}, ( + f"counters={written}: прогон без обрыва уходит в mark_done с этими counters — " + "без переписи диагноз отказов теряется" + ) + + @pytest.mark.asyncio async def test_real_platform_bans_still_abort_by_ratio() -> None: """Контроль: 14 настоящих AvitoBlockedError из 20 рвут прогон как раньше."""