fix(trade-in): развести окна ДомКлика — область не должна стартовать вместе с ЕКБ
All checks were successful
CI Trade-In / changes (pull_request) Successful in 10s
CI / changes (pull_request) Successful in 14s
CI Trade-In / browser-tests (pull_request) Has been skipped
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 5m11s

Миграция 306 поставила domclick_city_sweep_moskovskaya_oblast в окно 3-6 —
ровно то же, где сидит ЕКБ-строка domclick_city_sweep. Планировщик домклик-джобы
не сериализует: 17.09 обе новые строки заклеймлены в одну секунду (run 7333 и
7334, 05:00:55) и пошли параллельно.

Два свипа ДомКлика делят один браузерный сайдкар и один пул. В минуты
параллельного прогона tradein-browser держал 67% CPU, 1.67 из 2.5 ГиБ и 2297 PID,
часть запросов возвращалась как Page.goto Timeout 60000ms и socket hang up.
Узлов с provider_affinity='any' всего два (id 13, 14), их же берёт cian.

Миграция НЕ утверждает, что параллельность уронила сбор: померить это по ходу
прогона нечем — fetch_city копит лоты в память и сохраняет одним save_listings
после всех шести бакетов, так что ноль строк в listings в середине прогона —
норма (здоровый одиночный ЕКБ-свип 16.09, run 7219, тоже молчал 70 минут и затем
положил 6372/237). Окна разводятся по ресурсной причине, а не по этой метрике.

Область → 9-12: там нет ни одной домклик-строки. Москва остаётся в 0-3.
next_run_at выставлен явно и разнесён — иначе сохранились бы значения первого
клейма (область 20.09 04:11, внутри ЕКБ-окна) и коллизия повторилась бы.

Проверено сухим прогоном на проде под ROLLBACK: UPDATE 1 + UPDATE 1, итоговые
окна 3-6 (ЕКБ) / 0-3 Москва 20.09 00:30 / 9-12 область 20.09 09:30.

Claude-Session: https://claude.ai/code/session_01NQb6WeJtagZwZnUsSjDizs
This commit is contained in:
bot-backend 2026-09-17 08:50:04 +03:00
parent 1452e63eec
commit dba508f5ce

View file

@ -0,0 +1,60 @@
-- 307_domclick_msk_window_no_collision.sql
-- Развести окна ДомКлика: областной свип не должен стартовать вместе с ЕКБ-свипом.
--
-- Apply after: 306_scrape_schedules_seed_domclick_msk.sql
--
-- WHY:
-- Миграция 306 поставила 'domclick_city_sweep_moskovskaya_oblast' в окно 3-6 — РОВНО
-- то же, где с самого начала сидит ЕКБ-строка 'domclick_city_sweep'. Планировщик
-- домклик-джобы не сериализует: 17.09.2026 обе новые строки были заклеймлены в одну
-- секунду (run_id 7333 и 7334, 05:00:55) и пошли параллельно.
--
-- Почему это плохо, без домыслов о причинности: два свипа ДомКлика делят ОДИН
-- браузерный сайдкар и ОДИН пул. В минуты параллельного прогона tradein-browser
-- держал 67% CPU, 1.67 из 2.5 ГиБ и 2297 PID, а часть запросов возвращалась как
-- 'Page.goto: Timeout 60000ms' и 'socket hang up' → HTTP 500. Узлов с
-- provider_affinity='any' в пуле всего два (id 13 и 14) — их же берёт cian, так что
-- параллельная пара домклик-свипов забирает оба.
--
-- ЧЕГО ЭТА МИГРАЦИЯ НЕ УТВЕРЖДАЕТ: что параллельность уронила сбор. Померить это по
-- ходу прогона нечем — DomClickScraper.fetch_city копит лоты в память и сохраняет их
-- ОДНИМ save_listings после обхода всех шести бакетов, инкрементального сохранения
-- нет. Поэтому 'ноль строк в listings за 45 минут' — нормальное состояние середины
-- прогона (здоровый одиночный ЕКБ-свип 16.09, run 7219, тоже не писал ничего 70 минут
-- и затем положил 6372 seen / 237 new). Разводим окна по ресурсной причине выше, а не
-- по выводу из этой метрики.
--
-- Новое окно области — 9-12: там нет НИ ОДНОЙ домклик-строки (домклик-джобы всего
-- три: 'domclick_city_sweep' 3-6, 'domclick_city_sweep_moskva' 0-3 и
-- 'domclick_detail_backfill' 15-18). Москва остаётся в 0-3 — она и так единственный
-- домклик в этом окне.
--
-- next_run_at выставляется ЯВНО и разнесён: без этого строки сохранили бы значения,
-- посчитанные при первом клейме (Москва 20.09 01:46, область 20.09 04:11), а 04:11
-- попадает внутрь ЕКБ-окна 3-6 — та же коллизия повторилась бы через трое суток.
--
-- Скобки + 'AT TIME ZONE UTC' на РЕЗУЛЬТАТЕ, а не только внутри: next_run_at —
-- timestamptz, а date_trunc от naive-времени вернул бы timestamp без зоны, и приведение
-- поехало бы по таймзоне сессии. Здесь обе стороны явные.
--
-- ИДЕМПОТЕНТНОСТЬ: UPDATE ... WHERE source = '...' — повторный прогон переписывает те
-- же значения. enabled НЕ трогаем: если строку выключили вручную, она останется
-- выключенной.
BEGIN;
SET LOCAL lock_timeout = '5s';
UPDATE scrape_schedules
SET window_start_hour = 9,
window_end_hour = 12,
next_run_at = (date_trunc('day', now() AT TIME ZONE 'UTC')
+ interval '3 days 9 hours 30 minutes') AT TIME ZONE 'UTC'
WHERE source = 'domclick_city_sweep_moskovskaya_oblast';
UPDATE scrape_schedules
SET next_run_at = (date_trunc('day', now() AT TIME ZONE 'UTC')
+ interval '3 days 0 hours 30 minutes') AT TIME ZONE 'UTC'
WHERE source = 'domclick_city_sweep_moskva';
COMMIT;