fix(tradein/scrapers): ABORT-лог называл серию блоков, хотя рвал прогон по доле #3201

Merged
lekss361 merged 1 commit from fix/3184-abort-log-names-wrong-criterion into main 2026-08-28 20:27:37 +00:00
Collaborator

Нашёл на контрольном прогоне после мержа #3199.

Что произошло на проде

Прогон 5210: 20 попыток, 6 обогащено, 14 блоков. Оборвался по ratio-критерию — 14/20 это ровно порог 0.7. В лог ушло:

avito_detail_backfill: run_id=5210 ABORT -- 1 consecutive blocks, частая причина:
AvitoBlockedError: Avito detail firewall/soft-block (browser-mode) for <url> (14 из 14).
enriched=6 attempted=20

Число «1» верное: 19-я попытка была успехом, 20-я блоком, текущая серия равна единице. Но обрыв произошёл не по серии. Читатель видит величину, по которой обрыва быть не могло, и идёт искать баг в брейкере.

Причина ровно та же, что чинил #3178 у соседней строки: #3184 сменил критерий обрыва, а текст лога остался от прежнего.

Что в диффе

abort_reason() "ratio" / "safety_net" / None; should_abort() выражен через него — поведение не меняется
abort_explanation() текст с той величиной, по которой обрыв и произошёл
counters["abort_reason"] причина обрыва читается SQL-запросом по scrape_runs, а не грепом контейнера

Как теперь выглядит:

ABORT -- доля блоков 14/20 в окне (порог 70%), частая причина: ...
ABORT -- 5 блоков подряд без единого успеха (снапшот 5 короче окна 20), частая причина: ...

Тесты

Три новых, проверены мутацией источника — вернул старое сообщение и убрал ключ из counters, оба лог-теста покраснели:

  1. ratio-обрыв на точной раскладке прогона 5210 (блоки 2,3,5,6,7,8,9,11,12,13,14,16,17,20 — серия на обрыве = 1): требует 14/20 в логе и отсутствия слова consecutive.
  2. safety-net: требует 5 блоков подряд и отсутствия доля блоков. Без этого зеркала первый тест проходил бы и у сообщения, которое всегда печатает долю.
  3. прогон без обрыва (13/20) не пишет abort_reason — ключ означает «оборвались», а не «считали критерий».

33 passed в tests/tasks/test_avito_detail_backfill.py (было 30), ruff чист.

Границы

Поведение обрыва не трогаю — только его описание. Пороги, окно, safety-net остаются как в #3184. Домклик не трогаю (у него своя калибровка, #3189).

Refs #3184, #3178

Нашёл на контрольном прогоне после мержа #3199. ## Что произошло на проде Прогон **5210**: 20 попыток, 6 обогащено, 14 блоков. Оборвался по ratio-критерию — 14/20 это ровно порог 0.7. В лог ушло: ``` avito_detail_backfill: run_id=5210 ABORT -- 1 consecutive blocks, частая причина: AvitoBlockedError: Avito detail firewall/soft-block (browser-mode) for <url> (14 из 14). enriched=6 attempted=20 ``` Число «1» верное: 19-я попытка была успехом, 20-я блоком, текущая серия равна единице. Но обрыв произошёл **не по серии**. Читатель видит величину, по которой обрыва быть не могло, и идёт искать баг в брейкере. Причина ровно та же, что чинил #3178 у соседней строки: #3184 сменил критерий обрыва, а текст лога остался от прежнего. ## Что в диффе | | | |---|---| | `abort_reason()` | `"ratio"` / `"safety_net"` / `None`; `should_abort()` выражен через него — поведение не меняется | | `abort_explanation()` | текст с той величиной, по которой обрыв и произошёл | | `counters["abort_reason"]` | причина обрыва читается SQL-запросом по `scrape_runs`, а не грепом контейнера | Как теперь выглядит: ``` ABORT -- доля блоков 14/20 в окне (порог 70%), частая причина: ... ABORT -- 5 блоков подряд без единого успеха (снапшот 5 короче окна 20), частая причина: ... ``` ## Тесты Три новых, **проверены мутацией источника** — вернул старое сообщение и убрал ключ из counters, оба лог-теста покраснели: 1. ratio-обрыв на точной раскладке прогона 5210 (блоки 2,3,5,6,7,8,9,11,12,13,14,16,17,20 — серия на обрыве = 1): требует `14/20` в логе и отсутствия слова `consecutive`. 2. safety-net: требует `5 блоков подряд` и отсутствия `доля блоков`. Без этого зеркала первый тест проходил бы и у сообщения, которое всегда печатает долю. 3. прогон без обрыва (13/20) не пишет `abort_reason` — ключ означает «оборвались», а не «считали критерий». `33 passed` в `tests/tasks/test_avito_detail_backfill.py` (было 30), ruff чист. ## Границы Поведение обрыва не трогаю — только его описание. Пороги, окно, safety-net остаются как в #3184. Домклик не трогаю (у него своя калибровка, #3189). Refs #3184, #3178
bot-backend added 1 commit 2026-08-28 20:04:34 +00:00
fix(tradein/scrapers): ABORT-лог называл серию блоков, хотя рвал прогон по доле
All checks were successful
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / changes (pull_request) Successful in 10s
CI / backend-tests (pull_request) Has been skipped
CI Trade-In / changes (pull_request) Successful in 7s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 4m49s
8176e8d167
Прод-прогон 5210 оборвался по ratio-критерию — 14 блоков из 20, ровно порог 0.7 —
и отчитался строкой «ABORT -- 1 consecutive blocks». Число верное: последняя серия
в тот момент действительно равнялась единице (19-я попытка успех, 20-я блок).
Величина не та. Читатель лога видит цифру, по которой обрыва быть не могло, и идёт
искать несуществующий баг в брейкере.

Причина: #3184 заменил критерий обрыва на долю в скользящем окне, а текст лога
остался от прежнего критерия «N подряд» — то есть ровно та же болезнь, которую
#3178 лечил у соседней строки (литерал «IP rate-limited» вместо измеренной причины).

- BlockRatioBreaker.abort_reason() возвращает "ratio" / "safety_net" / None;
  should_abort() выражен через него, поведение не меняется.
- abort_explanation() даёт текст с той величиной, по которой обрыв и произошёл:
  доля печатает «доля блоков 14/20 в окне (порог 70%)», safety-net — «5 блоков
  подряд без единого успеха (снапшот 5 короче окна 20)».
- counters["abort_reason"] — чтобы причина обрыва читалась SQL-запросом по
  scrape_runs, а не грепом контейнера. Ключа нет, если прогон не обрывался.

Тесты (проверено мутацией источника — на прежнем сообщении оба падают):
- ratio-обрыв на раскладке прогона 5210 (серия на обрыве = 1) требует «14/20»
  в логе и отсутствия слова consecutive;
- safety-net требует «5 блоков подряд» и отсутствия «доля блоков» — без этого
  зеркала первый тест проходил бы и у сообщения, всегда печатающего долю;
- прогон без обрыва (13/20) не пишет abort_reason в counters.

Refs #3184, #3178
lekss361 merged commit cdcb152d76 into main 2026-08-28 20:27:36 +00:00
lekss361 deleted branch fix/3184-abort-log-names-wrong-criterion 2026-08-28 20:27:37 +00:00
Sign in to join this conversation.
No reviewers
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#3201
No description provided.