fix(scraper-kit): дрейн-метка interrupted=1 у domclick sweep и трёх full-load — резюм после SIGTERM для всех функций с чекпоинтом #3363

Merged
bot-backend merged 2 commits from fix/3355-drain-mark-fullloads into main 2026-09-05 19:28:25 +00:00
Collaborator

Closes #3355 (follow-up #3333/#3346). Четыре функции с живым done_buckets финализировали дрейн чистым done — резюм их не брал.

функция дрейн-точка резюм читает ключи? статус финализации (замер)
run_cian_full_load except RuntimeError "shutdown" да — skip_set из done_buckets, job с _pick_resume done
run_yandex_full_load там же частично: job'а в scheduler.py нет вовсе, единственный вход с resume_run_id — админский POST → метка диагностическая по факту done
run_avito_full_load там же да — оба job'а (avito_full_load + _exhaustive, #3315/#3358) done
run_domclick_city_sweep дрейн до SERP да — skip_buckets, чекпоинт унаследован при claim (#3074) done

done_buckets в payload не добавлялся (у full-load'ов уже был, у domclick — jsonb-мерж хранит унаследованный). Статус нулевого дрейна = done, honest-status гейты его не диверят — закреплено тестом (покраснеет при изменении гейтов).

Тесты

test_3355_drain_mark_full_loads.py: 356 passed, 1 skipped (-k drain/sweep/resume/checkpoint/full_load). Фальсификация (откат только avito-хунка): avito full-load: дрейн без метки — бан-бюджет тратится на уже собранные бакеты + дрейн со статусом 'done' не подхвачен резюмом: {… 'resume_reason': 'status_done'}; cian/yandex/domclick зелёные.

Follow-up

run_yandex_full_load без job'а в планировщике — отдельный issue (нужен ли он в расписании).

Closes #3355 (follow-up #3333/#3346). Четыре функции с живым `done_buckets` финализировали дрейн чистым `done` — резюм их не брал. | функция | дрейн-точка | резюм читает ключи? | статус финализации (замер) | |---|---|---|---| | `run_cian_full_load` | `except RuntimeError "shutdown"` | да — `skip_set` из `done_buckets`, job с `_pick_resume` | `done` | | `run_yandex_full_load` | там же | **частично: job'а в scheduler.py нет вовсе**, единственный вход с `resume_run_id` — админский POST → метка диагностическая по факту | `done` | | `run_avito_full_load` | там же | да — оба job'а (`avito_full_load` + `_exhaustive`, #3315/#3358) | `done` | | `run_domclick_city_sweep` | дрейн до SERP | да — `skip_buckets`, чекпоинт унаследован при claim (#3074) | `done` | `done_buckets` в payload не добавлялся (у full-load'ов уже был, у domclick — jsonb-мерж хранит унаследованный). Статус нулевого дрейна = `done`, honest-status гейты его не диверят — закреплено тестом (покраснеет при изменении гейтов). ## Тесты `test_3355_drain_mark_full_loads.py`: `356 passed, 1 skipped` (-k drain/sweep/resume/checkpoint/full_load). Фальсификация (откат только avito-хунка): `avito full-load: дрейн без метки — бан-бюджет тратится на уже собранные бакеты` + `дрейн со статусом 'done' не подхвачен резюмом: {… 'resume_reason': 'status_done'}`; cian/yandex/domclick зелёные. ## Follow-up `run_yandex_full_load` без job'а в планировщике — отдельный issue (нужен ли он в расписании).
bot-backend added 1 commit 2026-09-05 19:02:51 +00:00
fix(scraper): пометить SIGTERM-дрейн interrupted=1 у full-load'ов и domclick-свипа
All checks were successful
CI Trade-In / changes (pull_request) Successful in 9s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 12s
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-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 5m5s
f6cf948358
После #3330/#3346 резюм берёт 'done' только с counters.interrupted=1, но четыре
функции с живым чекпоинтом done_buckets финализировали дрейн чистым 'done':
cian/yandex/avito full-load (ветка RuntimeError("shutdown")) и domclick city
sweep (дрейн до SERP). Оборванный обход был неотличим от полного, а собранные
бакеты никто не подхватывал — у avito это ещё и бан-бюджет (#3315).

done_buckets в domclick-payload не добавляем: чекпоинт унаследован при claim
(#3074), jsonb-мерж его сохраняет.

Closes #3355
Light1YT added 1 commit 2026-09-05 19:22:05 +00:00
fix(scraper): дрейн domclick сохраняет чекпоинт, дрейн cian-detail помечается
All checks were successful
CI Trade-In / changes (pull_request) Successful in 7s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 9s
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-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 5m0s
12945d7b2f
Ревью PR #3363:

1. domclick city sweep: комментарий обещал, что унаследованный при claim
   чекпоинт переживёт дрейн «jsonb-мержем» — мержа нет. domclick пишет
   counters через app-level scrape_runs (update_heartbeat/mark_done делают
   `counters = CAST(:counters AS jsonb)`, полная перезапись), а scheduler
   при claim done_buckets не наследует. Дрейн закрывал прогон с ПУСТЫМ
   чекпоинтом, резюм пересобирал все шесть корзин. Чтение чекпоинта поднято
   выше ранних выходов, дрейн-payload несёт `done_buckets` явно — как уже
   делает ban-ветка (except NoProxyAvailableError) той же функции.

2. cian full-load, detail-фаза: второй ранний выход по shutdown_requested()
   делал `break` и уходил в обычный mark_done — SERP целый, обогащение
   обрезано, а прогон выглядел полным. Теперь тот же sentinel
   RuntimeError("shutdown"), что и в _on_bucket: interrupted=1 + done_buckets.

3. yandex/avito full-load проверены: по одному shutdown-сайту в _on_bucket,
   detail-фазы нет вовсе — аналогичного дефекта нет.

Тесты: чекпоинт дрейна domclick сверяется ПО ЗНАЧЕНИЮ в обеих записях
(heartbeat + финализатор); дрейн cian в detail-фазе даёт interrupted=1.
bot-backend merged commit 83946e5d4f into main 2026-09-05 19:28:25 +00:00
Author
Collaborator

Датированная приёмка (первый реальный SIGTERM-drain, деплой 07.09 02:36 UTC) — ОТРИЦАТЕЛЬНЫЙ результат для app-task бэкфиллов: in-flight были cian_detail_backfill 6167 и cian_history_backfill 6173; после «drain exceeded 100s grace — hard-cancelling» обе строки остались running и boot-reap нового контейнера сделал их zombie (boot_reaped=true), interrupted не записан. Для kit-свипов/full-load случай пока не наблюдался (в момент деплоя их не было). Разбор и фикс в одном месте (kit-scheduler при hard-cancel) — #3391.

**Датированная приёмка (первый реальный SIGTERM-drain, деплой 07.09 02:36 UTC) — ОТРИЦАТЕЛЬНЫЙ результат для app-task бэкфиллов:** in-flight были `cian_detail_backfill` 6167 и `cian_history_backfill` 6173; после «drain exceeded 100s grace — hard-cancelling» обе строки остались `running` и boot-reap нового контейнера сделал их `zombie` (`boot_reaped=true`), `interrupted` не записан. Для kit-свипов/full-load случай пока не наблюдался (в момент деплоя их не было). Разбор и фикс в одном месте (kit-scheduler при hard-cancel) — #3391.
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
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#3363
No description provided.